/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to codeigniter/js/ace/ace.js

  • Committer: Gustav Hatvigsson
  • Date: 2013-05-30 12:02:31 UTC
  • mfrom: (85.1.28 lenasys)
  • Revision ID: gustav.hartvigsson@gmail.com-20130530120231-ttqgqjqw2w8enn7g
Merged Ohlsons changes:
added function to get ssn and name for the registrationspages in the user model.
added the registrationpage for students.
edited the registration page for instructors
edited the css for both the registrationpages
minor fix to registration css

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
(function() {
 
32
 
 
33
var ACE_NAMESPACE = "";
 
34
 
 
35
var global = (function() {
 
36
    return this;
 
37
})();
 
38
 
 
39
 
 
40
if (!ACE_NAMESPACE && typeof requirejs !== "undefined")
 
41
    return;
 
42
 
 
43
 
 
44
var _define = function(module, deps, payload) {
 
45
    if (typeof module !== 'string') {
 
46
        if (_define.original)
 
47
            _define.original.apply(window, arguments);
 
48
        else {
 
49
            console.error('dropping module because define wasn\'t a string.');
 
50
            console.trace();
 
51
        }
 
52
        return;
 
53
    }
 
54
 
 
55
    if (arguments.length == 2)
 
56
        payload = deps;
 
57
 
 
58
    if (!_define.modules)
 
59
        _define.modules = {};
 
60
 
 
61
    _define.modules[module] = payload;
 
62
};
 
63
var _require = function(parentId, module, callback) {
 
64
    if (Object.prototype.toString.call(module) === "[object Array]") {
 
65
        var params = [];
 
66
        for (var i = 0, l = module.length; i < l; ++i) {
 
67
            var dep = lookup(parentId, module[i]);
 
68
            if (!dep && _require.original)
 
69
                return _require.original.apply(window, arguments);
 
70
            params.push(dep);
 
71
        }
 
72
        if (callback) {
 
73
            callback.apply(null, params);
 
74
        }
 
75
    }
 
76
    else if (typeof module === 'string') {
 
77
        var payload = lookup(parentId, module);
 
78
        if (!payload && _require.original)
 
79
            return _require.original.apply(window, arguments);
 
80
 
 
81
        if (callback) {
 
82
            callback();
 
83
        }
 
84
 
 
85
        return payload;
 
86
    }
 
87
    else {
 
88
        if (_require.original)
 
89
            return _require.original.apply(window, arguments);
 
90
    }
 
91
};
 
92
 
 
93
var normalizeModule = function(parentId, moduleName) {
 
94
    if (moduleName.indexOf("!") !== -1) {
 
95
        var chunks = moduleName.split("!");
 
96
        return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
 
97
    }
 
98
    if (moduleName.charAt(0) == ".") {
 
99
        var base = parentId.split("/").slice(0, -1).join("/");
 
100
        moduleName = base + "/" + moduleName;
 
101
 
 
102
        while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
 
103
            var previous = moduleName;
 
104
            moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
 
105
        }
 
106
    }
 
107
 
 
108
    return moduleName;
 
109
};
 
110
var lookup = function(parentId, moduleName) {
 
111
 
 
112
    moduleName = normalizeModule(parentId, moduleName);
 
113
 
 
114
    var module = _define.modules[moduleName];
 
115
    if (!module) {
 
116
        return null;
 
117
    }
 
118
 
 
119
    if (typeof module === 'function') {
 
120
        var exports = {};
 
121
        var mod = {
 
122
            id: moduleName,
 
123
            uri: '',
 
124
            exports: exports,
 
125
            packaged: true
 
126
        };
 
127
 
 
128
        var req = function(module, callback) {
 
129
            return _require(moduleName, module, callback);
 
130
        };
 
131
 
 
132
        var returnValue = module(req, exports, mod);
 
133
        exports = returnValue || mod.exports;
 
134
        _define.modules[moduleName] = exports;
 
135
        return exports;
 
136
    }
 
137
 
 
138
    return module;
 
139
};
 
140
 
 
141
function exportAce(ns) {
 
142
    var require = function(module, callback) {
 
143
        return _require("", module, callback);
 
144
    };    
 
145
 
 
146
    var root = global;
 
147
    if (ns) {
 
148
        if (!global[ns])
 
149
            global[ns] = {};
 
150
        root = global[ns];
 
151
    }
 
152
 
 
153
    if (!root.define || !root.define.packaged) {
 
154
        _define.original = root.define;
 
155
        root.define = _define;
 
156
        root.define.packaged = true;
 
157
    }
 
158
 
 
159
    if (!root.require || !root.require.packaged) {
 
160
        _require.original = root.require;
 
161
        root.require = require;
 
162
        root.require.packaged = true;
 
163
    }
 
164
}
 
165
 
 
166
exportAce(ACE_NAMESPACE);
 
167
 
 
168
})();
 
169
 
 
170
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/multi_select', 'ace/worker/worker_client', 'ace/keyboard/hash_handler', 'ace/placeholder', 'ace/mode/folding/fold_mode', 'ace/theme/textmate', 'ace/config'], function(require, exports, module) {
 
171
 
 
172
 
 
173
require("./lib/fixoldbrowsers");
 
174
 
 
175
var dom = require("./lib/dom");
 
176
var event = require("./lib/event");
 
177
 
 
178
var Editor = require("./editor").Editor;
 
179
var EditSession = require("./edit_session").EditSession;
 
180
var UndoManager = require("./undomanager").UndoManager;
 
181
var Renderer = require("./virtual_renderer").VirtualRenderer;
 
182
var MultiSelect = require("./multi_select").MultiSelect;
 
183
require("./worker/worker_client");
 
184
require("./keyboard/hash_handler");
 
185
require("./placeholder");
 
186
require("./mode/folding/fold_mode");
 
187
require("./theme/textmate");
 
188
 
 
189
exports.config = require("./config");
 
190
exports.require = require;
 
191
exports.edit = function(el) {
 
192
    if (typeof(el) == "string") {
 
193
        var _id = el;
 
194
        var el = document.getElementById(_id);
 
195
        if (!el)
 
196
            throw "ace.edit can't find div #" + _id;
 
197
    }
 
198
 
 
199
    if (el.env && el.env.editor instanceof Editor)
 
200
        return el.env.editor;
 
201
 
 
202
    var doc = exports.createEditSession(dom.getInnerText(el));
 
203
    el.innerHTML = '';
 
204
 
 
205
    var editor = new Editor(new Renderer(el));
 
206
    new MultiSelect(editor);
 
207
    editor.setSession(doc);
 
208
 
 
209
    var env = {
 
210
        document: doc,
 
211
        editor: editor,
 
212
        onResize: editor.resize.bind(editor, null)
 
213
    };
 
214
    event.addListener(window, "resize", env.onResize);
 
215
    editor.on("destroy", function() {
 
216
        event.removeListener(window, "resize", env.onResize);
 
217
    });
 
218
    el.env = editor.env = env;
 
219
    return editor;
 
220
};
 
221
exports.createEditSession = function(text, mode) {
 
222
    var doc = new EditSession(text, doc);
 
223
    doc.setUndoManager(new UndoManager());
 
224
    return doc;
 
225
}
 
226
exports.EditSession = EditSession;
 
227
exports.UndoManager = UndoManager;
 
228
});
 
229
 
 
230
define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
 
231
 
 
232
 
 
233
require("./regexp");
 
234
require("./es5-shim");
 
235
 
 
236
});
 
237
 
 
238
define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
 
239
 
 
240
    var real = {
 
241
            exec: RegExp.prototype.exec,
 
242
            test: RegExp.prototype.test,
 
243
            match: String.prototype.match,
 
244
            replace: String.prototype.replace,
 
245
            split: String.prototype.split
 
246
        },
 
247
        compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
 
248
        compliantLastIndexIncrement = function () {
 
249
            var x = /^/g;
 
250
            real.test.call(x, "");
 
251
            return !x.lastIndex;
 
252
        }();
 
253
 
 
254
    if (compliantLastIndexIncrement && compliantExecNpcg)
 
255
        return;
 
256
    RegExp.prototype.exec = function (str) {
 
257
        var match = real.exec.apply(this, arguments),
 
258
            name, r2;
 
259
        if ( typeof(str) == 'string' && match) {
 
260
            if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
 
261
                r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
 
262
                real.replace.call(str.slice(match.index), r2, function () {
 
263
                    for (var i = 1; i < arguments.length - 2; i++) {
 
264
                        if (arguments[i] === undefined)
 
265
                            match[i] = undefined;
 
266
                    }
 
267
                });
 
268
            }
 
269
            if (this._xregexp && this._xregexp.captureNames) {
 
270
                for (var i = 1; i < match.length; i++) {
 
271
                    name = this._xregexp.captureNames[i - 1];
 
272
                    if (name)
 
273
                       match[name] = match[i];
 
274
                }
 
275
            }
 
276
            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
 
277
                this.lastIndex--;
 
278
        }
 
279
        return match;
 
280
    };
 
281
    if (!compliantLastIndexIncrement) {
 
282
        RegExp.prototype.test = function (str) {
 
283
            var match = real.exec.call(this, str);
 
284
            if (match && this.global && !match[0].length && (this.lastIndex > match.index))
 
285
                this.lastIndex--;
 
286
            return !!match;
 
287
        };
 
288
    }
 
289
 
 
290
    function getNativeFlags (regex) {
 
291
        return (regex.global     ? "g" : "") +
 
292
               (regex.ignoreCase ? "i" : "") +
 
293
               (regex.multiline  ? "m" : "") +
 
294
               (regex.extended   ? "x" : "") + // Proposed for ES4; included in AS3
 
295
               (regex.sticky     ? "y" : "");
 
296
    }
 
297
 
 
298
    function indexOf (array, item, from) {
 
299
        if (Array.prototype.indexOf) // Use the native array method if available
 
300
            return array.indexOf(item, from);
 
301
        for (var i = from || 0; i < array.length; i++) {
 
302
            if (array[i] === item)
 
303
                return i;
 
304
        }
 
305
        return -1;
 
306
    }
 
307
 
 
308
});
 
309
 
 
310
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
 
311
 
 
312
function Empty() {}
 
313
 
 
314
if (!Function.prototype.bind) {
 
315
    Function.prototype.bind = function bind(that) { // .length is 1
 
316
        var target = this;
 
317
        if (typeof target != "function") {
 
318
            throw new TypeError("Function.prototype.bind called on incompatible " + target);
 
319
        }
 
320
        var args = slice.call(arguments, 1); // for normal call
 
321
        var bound = function () {
 
322
 
 
323
            if (this instanceof bound) {
 
324
 
 
325
                var result = target.apply(
 
326
                    this,
 
327
                    args.concat(slice.call(arguments))
 
328
                );
 
329
                if (Object(result) === result) {
 
330
                    return result;
 
331
                }
 
332
                return this;
 
333
 
 
334
            } else {
 
335
                return target.apply(
 
336
                    that,
 
337
                    args.concat(slice.call(arguments))
 
338
                );
 
339
 
 
340
            }
 
341
 
 
342
        };
 
343
        if(target.prototype) {
 
344
            Empty.prototype = target.prototype;
 
345
            bound.prototype = new Empty();
 
346
            Empty.prototype = null;
 
347
        }
 
348
        return bound;
 
349
    };
 
350
}
 
351
var call = Function.prototype.call;
 
352
var prototypeOfArray = Array.prototype;
 
353
var prototypeOfObject = Object.prototype;
 
354
var slice = prototypeOfArray.slice;
 
355
var _toString = call.bind(prototypeOfObject.toString);
 
356
var owns = call.bind(prototypeOfObject.hasOwnProperty);
 
357
var defineGetter;
 
358
var defineSetter;
 
359
var lookupGetter;
 
360
var lookupSetter;
 
361
var supportsAccessors;
 
362
if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
 
363
    defineGetter = call.bind(prototypeOfObject.__defineGetter__);
 
364
    defineSetter = call.bind(prototypeOfObject.__defineSetter__);
 
365
    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
 
366
    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
 
367
}
 
368
if ([1,2].splice(0).length != 2) {
 
369
    if(function() { // test IE < 9 to splice bug - see issue #138
 
370
        function makeArray(l) {
 
371
            var a = new Array(l+2);
 
372
            a[0] = a[1] = 0;
 
373
            return a;
 
374
        }
 
375
        var array = [], lengthBefore;
 
376
        
 
377
        array.splice.apply(array, makeArray(20));
 
378
        array.splice.apply(array, makeArray(26));
 
379
 
 
380
        lengthBefore = array.length; //46
 
381
        array.splice(5, 0, "XXX"); // add one element
 
382
 
 
383
        lengthBefore + 1 == array.length
 
384
 
 
385
        if (lengthBefore + 1 == array.length) {
 
386
            return true;// has right splice implementation without bugs
 
387
        }
 
388
    }()) {//IE 6/7
 
389
        var array_splice = Array.prototype.splice;
 
390
        Array.prototype.splice = function(start, deleteCount) {
 
391
            if (!arguments.length) {
 
392
                return [];
 
393
            } else {
 
394
                return array_splice.apply(this, [
 
395
                    start === void 0 ? 0 : start,
 
396
                    deleteCount === void 0 ? (this.length - start) : deleteCount
 
397
                ].concat(slice.call(arguments, 2)))
 
398
            }
 
399
        };
 
400
    } else {//IE8
 
401
        Array.prototype.splice = function(pos, removeCount){
 
402
            var length = this.length;
 
403
            if (pos > 0) {
 
404
                if (pos > length)
 
405
                    pos = length;
 
406
            } else if (pos == void 0) {
 
407
                pos = 0;
 
408
            } else if (pos < 0) {
 
409
                pos = Math.max(length + pos, 0);
 
410
            }
 
411
 
 
412
            if (!(pos+removeCount < length))
 
413
                removeCount = length - pos;
 
414
 
 
415
            var removed = this.slice(pos, pos+removeCount);
 
416
            var insert = slice.call(arguments, 2);
 
417
            var add = insert.length;            
 
418
            if (pos === length) {
 
419
                if (add) {
 
420
                    this.push.apply(this, insert);
 
421
                }
 
422
            } else {
 
423
                var remove = Math.min(removeCount, length - pos);
 
424
                var tailOldPos = pos + remove;
 
425
                var tailNewPos = tailOldPos + add - remove;
 
426
                var tailCount = length - tailOldPos;
 
427
                var lengthAfterRemove = length - remove;
 
428
 
 
429
                if (tailNewPos < tailOldPos) { // case A
 
430
                    for (var i = 0; i < tailCount; ++i) {
 
431
                        this[tailNewPos+i] = this[tailOldPos+i];
 
432
                    }
 
433
                } else if (tailNewPos > tailOldPos) { // case B
 
434
                    for (i = tailCount; i--; ) {
 
435
                        this[tailNewPos+i] = this[tailOldPos+i];
 
436
                    }
 
437
                } // else, add == remove (nothing to do)
 
438
 
 
439
                if (add && pos === lengthAfterRemove) {
 
440
                    this.length = lengthAfterRemove; // truncate array
 
441
                    this.push.apply(this, insert);
 
442
                } else {
 
443
                    this.length = lengthAfterRemove + add; // reserves space
 
444
                    for (i = 0; i < add; ++i) {
 
445
                        this[pos+i] = insert[i];
 
446
                    }
 
447
                }
 
448
            }
 
449
            return removed;
 
450
        };
 
451
    }
 
452
}
 
453
if (!Array.isArray) {
 
454
    Array.isArray = function isArray(obj) {
 
455
        return _toString(obj) == "[object Array]";
 
456
    };
 
457
}
 
458
var boxedString = Object("a"),
 
459
    splitString = boxedString[0] != "a" || !(0 in boxedString);
 
460
 
 
461
if (!Array.prototype.forEach) {
 
462
    Array.prototype.forEach = function forEach(fun /*, thisp*/) {
 
463
        var object = toObject(this),
 
464
            self = splitString && _toString(this) == "[object String]" ?
 
465
                this.split("") :
 
466
                object,
 
467
            thisp = arguments[1],
 
468
            i = -1,
 
469
            length = self.length >>> 0;
 
470
        if (_toString(fun) != "[object Function]") {
 
471
            throw new TypeError(); // TODO message
 
472
        }
 
473
 
 
474
        while (++i < length) {
 
475
            if (i in self) {
 
476
                fun.call(thisp, self[i], i, object);
 
477
            }
 
478
        }
 
479
    };
 
480
}
 
481
if (!Array.prototype.map) {
 
482
    Array.prototype.map = function map(fun /*, thisp*/) {
 
483
        var object = toObject(this),
 
484
            self = splitString && _toString(this) == "[object String]" ?
 
485
                this.split("") :
 
486
                object,
 
487
            length = self.length >>> 0,
 
488
            result = Array(length),
 
489
            thisp = arguments[1];
 
490
        if (_toString(fun) != "[object Function]") {
 
491
            throw new TypeError(fun + " is not a function");
 
492
        }
 
493
 
 
494
        for (var i = 0; i < length; i++) {
 
495
            if (i in self)
 
496
                result[i] = fun.call(thisp, self[i], i, object);
 
497
        }
 
498
        return result;
 
499
    };
 
500
}
 
501
if (!Array.prototype.filter) {
 
502
    Array.prototype.filter = function filter(fun /*, thisp */) {
 
503
        var object = toObject(this),
 
504
            self = splitString && _toString(this) == "[object String]" ?
 
505
                this.split("") :
 
506
                    object,
 
507
            length = self.length >>> 0,
 
508
            result = [],
 
509
            value,
 
510
            thisp = arguments[1];
 
511
        if (_toString(fun) != "[object Function]") {
 
512
            throw new TypeError(fun + " is not a function");
 
513
        }
 
514
 
 
515
        for (var i = 0; i < length; i++) {
 
516
            if (i in self) {
 
517
                value = self[i];
 
518
                if (fun.call(thisp, value, i, object)) {
 
519
                    result.push(value);
 
520
                }
 
521
            }
 
522
        }
 
523
        return result;
 
524
    };
 
525
}
 
526
if (!Array.prototype.every) {
 
527
    Array.prototype.every = function every(fun /*, thisp */) {
 
528
        var object = toObject(this),
 
529
            self = splitString && _toString(this) == "[object String]" ?
 
530
                this.split("") :
 
531
                object,
 
532
            length = self.length >>> 0,
 
533
            thisp = arguments[1];
 
534
        if (_toString(fun) != "[object Function]") {
 
535
            throw new TypeError(fun + " is not a function");
 
536
        }
 
537
 
 
538
        for (var i = 0; i < length; i++) {
 
539
            if (i in self && !fun.call(thisp, self[i], i, object)) {
 
540
                return false;
 
541
            }
 
542
        }
 
543
        return true;
 
544
    };
 
545
}
 
546
if (!Array.prototype.some) {
 
547
    Array.prototype.some = function some(fun /*, thisp */) {
 
548
        var object = toObject(this),
 
549
            self = splitString && _toString(this) == "[object String]" ?
 
550
                this.split("") :
 
551
                object,
 
552
            length = self.length >>> 0,
 
553
            thisp = arguments[1];
 
554
        if (_toString(fun) != "[object Function]") {
 
555
            throw new TypeError(fun + " is not a function");
 
556
        }
 
557
 
 
558
        for (var i = 0; i < length; i++) {
 
559
            if (i in self && fun.call(thisp, self[i], i, object)) {
 
560
                return true;
 
561
            }
 
562
        }
 
563
        return false;
 
564
    };
 
565
}
 
566
if (!Array.prototype.reduce) {
 
567
    Array.prototype.reduce = function reduce(fun /*, initial*/) {
 
568
        var object = toObject(this),
 
569
            self = splitString && _toString(this) == "[object String]" ?
 
570
                this.split("") :
 
571
                object,
 
572
            length = self.length >>> 0;
 
573
        if (_toString(fun) != "[object Function]") {
 
574
            throw new TypeError(fun + " is not a function");
 
575
        }
 
576
        if (!length && arguments.length == 1) {
 
577
            throw new TypeError("reduce of empty array with no initial value");
 
578
        }
 
579
 
 
580
        var i = 0;
 
581
        var result;
 
582
        if (arguments.length >= 2) {
 
583
            result = arguments[1];
 
584
        } else {
 
585
            do {
 
586
                if (i in self) {
 
587
                    result = self[i++];
 
588
                    break;
 
589
                }
 
590
                if (++i >= length) {
 
591
                    throw new TypeError("reduce of empty array with no initial value");
 
592
                }
 
593
            } while (true);
 
594
        }
 
595
 
 
596
        for (; i < length; i++) {
 
597
            if (i in self) {
 
598
                result = fun.call(void 0, result, self[i], i, object);
 
599
            }
 
600
        }
 
601
 
 
602
        return result;
 
603
    };
 
604
}
 
605
if (!Array.prototype.reduceRight) {
 
606
    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
 
607
        var object = toObject(this),
 
608
            self = splitString && _toString(this) == "[object String]" ?
 
609
                this.split("") :
 
610
                object,
 
611
            length = self.length >>> 0;
 
612
        if (_toString(fun) != "[object Function]") {
 
613
            throw new TypeError(fun + " is not a function");
 
614
        }
 
615
        if (!length && arguments.length == 1) {
 
616
            throw new TypeError("reduceRight of empty array with no initial value");
 
617
        }
 
618
 
 
619
        var result, i = length - 1;
 
620
        if (arguments.length >= 2) {
 
621
            result = arguments[1];
 
622
        } else {
 
623
            do {
 
624
                if (i in self) {
 
625
                    result = self[i--];
 
626
                    break;
 
627
                }
 
628
                if (--i < 0) {
 
629
                    throw new TypeError("reduceRight of empty array with no initial value");
 
630
                }
 
631
            } while (true);
 
632
        }
 
633
 
 
634
        do {
 
635
            if (i in this) {
 
636
                result = fun.call(void 0, result, self[i], i, object);
 
637
            }
 
638
        } while (i--);
 
639
 
 
640
        return result;
 
641
    };
 
642
}
 
643
if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
 
644
    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
 
645
        var self = splitString && _toString(this) == "[object String]" ?
 
646
                this.split("") :
 
647
                toObject(this),
 
648
            length = self.length >>> 0;
 
649
 
 
650
        if (!length) {
 
651
            return -1;
 
652
        }
 
653
 
 
654
        var i = 0;
 
655
        if (arguments.length > 1) {
 
656
            i = toInteger(arguments[1]);
 
657
        }
 
658
        i = i >= 0 ? i : Math.max(0, length + i);
 
659
        for (; i < length; i++) {
 
660
            if (i in self && self[i] === sought) {
 
661
                return i;
 
662
            }
 
663
        }
 
664
        return -1;
 
665
    };
 
666
}
 
667
if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
 
668
    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
 
669
        var self = splitString && _toString(this) == "[object String]" ?
 
670
                this.split("") :
 
671
                toObject(this),
 
672
            length = self.length >>> 0;
 
673
 
 
674
        if (!length) {
 
675
            return -1;
 
676
        }
 
677
        var i = length - 1;
 
678
        if (arguments.length > 1) {
 
679
            i = Math.min(i, toInteger(arguments[1]));
 
680
        }
 
681
        i = i >= 0 ? i : length - Math.abs(i);
 
682
        for (; i >= 0; i--) {
 
683
            if (i in self && sought === self[i]) {
 
684
                return i;
 
685
            }
 
686
        }
 
687
        return -1;
 
688
    };
 
689
}
 
690
if (!Object.getPrototypeOf) {
 
691
    Object.getPrototypeOf = function getPrototypeOf(object) {
 
692
        return object.__proto__ || (
 
693
            object.constructor ?
 
694
            object.constructor.prototype :
 
695
            prototypeOfObject
 
696
        );
 
697
    };
 
698
}
 
699
if (!Object.getOwnPropertyDescriptor) {
 
700
    var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
 
701
                         "non-object: ";
 
702
    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
 
703
        if ((typeof object != "object" && typeof object != "function") || object === null)
 
704
            throw new TypeError(ERR_NON_OBJECT + object);
 
705
        if (!owns(object, property))
 
706
            return;
 
707
 
 
708
        var descriptor, getter, setter;
 
709
        descriptor =  { enumerable: true, configurable: true };
 
710
        if (supportsAccessors) {
 
711
            var prototype = object.__proto__;
 
712
            object.__proto__ = prototypeOfObject;
 
713
 
 
714
            var getter = lookupGetter(object, property);
 
715
            var setter = lookupSetter(object, property);
 
716
            object.__proto__ = prototype;
 
717
 
 
718
            if (getter || setter) {
 
719
                if (getter) descriptor.get = getter;
 
720
                if (setter) descriptor.set = setter;
 
721
                return descriptor;
 
722
            }
 
723
        }
 
724
        descriptor.value = object[property];
 
725
        return descriptor;
 
726
    };
 
727
}
 
728
if (!Object.getOwnPropertyNames) {
 
729
    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
 
730
        return Object.keys(object);
 
731
    };
 
732
}
 
733
if (!Object.create) {
 
734
    var createEmpty;
 
735
    if (Object.prototype.__proto__ === null) {
 
736
        createEmpty = function () {
 
737
            return { "__proto__": null };
 
738
        };
 
739
    } else {
 
740
        createEmpty = function () {
 
741
            var empty = {};
 
742
            for (var i in empty)
 
743
                empty[i] = null;
 
744
            empty.constructor =
 
745
            empty.hasOwnProperty =
 
746
            empty.propertyIsEnumerable =
 
747
            empty.isPrototypeOf =
 
748
            empty.toLocaleString =
 
749
            empty.toString =
 
750
            empty.valueOf =
 
751
            empty.__proto__ = null;
 
752
            return empty;
 
753
        }
 
754
    }
 
755
 
 
756
    Object.create = function create(prototype, properties) {
 
757
        var object;
 
758
        if (prototype === null) {
 
759
            object = createEmpty();
 
760
        } else {
 
761
            if (typeof prototype != "object")
 
762
                throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
 
763
            var Type = function () {};
 
764
            Type.prototype = prototype;
 
765
            object = new Type();
 
766
            object.__proto__ = prototype;
 
767
        }
 
768
        if (properties !== void 0)
 
769
            Object.defineProperties(object, properties);
 
770
        return object;
 
771
    };
 
772
}
 
773
 
 
774
function doesDefinePropertyWork(object) {
 
775
    try {
 
776
        Object.defineProperty(object, "sentinel", {});
 
777
        return "sentinel" in object;
 
778
    } catch (exception) {
 
779
    }
 
780
}
 
781
if (Object.defineProperty) {
 
782
    var definePropertyWorksOnObject = doesDefinePropertyWork({});
 
783
    var definePropertyWorksOnDom = typeof document == "undefined" ||
 
784
        doesDefinePropertyWork(document.createElement("div"));
 
785
    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
 
786
        var definePropertyFallback = Object.defineProperty;
 
787
    }
 
788
}
 
789
 
 
790
if (!Object.defineProperty || definePropertyFallback) {
 
791
    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
 
792
    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
 
793
    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
 
794
                                      "on this javascript engine";
 
795
 
 
796
    Object.defineProperty = function defineProperty(object, property, descriptor) {
 
797
        if ((typeof object != "object" && typeof object != "function") || object === null)
 
798
            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
 
799
        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
 
800
            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
 
801
        if (definePropertyFallback) {
 
802
            try {
 
803
                return definePropertyFallback.call(Object, object, property, descriptor);
 
804
            } catch (exception) {
 
805
            }
 
806
        }
 
807
        if (owns(descriptor, "value")) {
 
808
 
 
809
            if (supportsAccessors && (lookupGetter(object, property) ||
 
810
                                      lookupSetter(object, property)))
 
811
            {
 
812
                var prototype = object.__proto__;
 
813
                object.__proto__ = prototypeOfObject;
 
814
                delete object[property];
 
815
                object[property] = descriptor.value;
 
816
                object.__proto__ = prototype;
 
817
            } else {
 
818
                object[property] = descriptor.value;
 
819
            }
 
820
        } else {
 
821
            if (!supportsAccessors)
 
822
                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
 
823
            if (owns(descriptor, "get"))
 
824
                defineGetter(object, property, descriptor.get);
 
825
            if (owns(descriptor, "set"))
 
826
                defineSetter(object, property, descriptor.set);
 
827
        }
 
828
 
 
829
        return object;
 
830
    };
 
831
}
 
832
if (!Object.defineProperties) {
 
833
    Object.defineProperties = function defineProperties(object, properties) {
 
834
        for (var property in properties) {
 
835
            if (owns(properties, property))
 
836
                Object.defineProperty(object, property, properties[property]);
 
837
        }
 
838
        return object;
 
839
    };
 
840
}
 
841
if (!Object.seal) {
 
842
    Object.seal = function seal(object) {
 
843
        return object;
 
844
    };
 
845
}
 
846
if (!Object.freeze) {
 
847
    Object.freeze = function freeze(object) {
 
848
        return object;
 
849
    };
 
850
}
 
851
try {
 
852
    Object.freeze(function () {});
 
853
} catch (exception) {
 
854
    Object.freeze = (function freeze(freezeObject) {
 
855
        return function freeze(object) {
 
856
            if (typeof object == "function") {
 
857
                return object;
 
858
            } else {
 
859
                return freezeObject(object);
 
860
            }
 
861
        };
 
862
    })(Object.freeze);
 
863
}
 
864
if (!Object.preventExtensions) {
 
865
    Object.preventExtensions = function preventExtensions(object) {
 
866
        return object;
 
867
    };
 
868
}
 
869
if (!Object.isSealed) {
 
870
    Object.isSealed = function isSealed(object) {
 
871
        return false;
 
872
    };
 
873
}
 
874
if (!Object.isFrozen) {
 
875
    Object.isFrozen = function isFrozen(object) {
 
876
        return false;
 
877
    };
 
878
}
 
879
if (!Object.isExtensible) {
 
880
    Object.isExtensible = function isExtensible(object) {
 
881
        if (Object(object) === object) {
 
882
            throw new TypeError(); // TODO message
 
883
        }
 
884
        var name = '';
 
885
        while (owns(object, name)) {
 
886
            name += '?';
 
887
        }
 
888
        object[name] = true;
 
889
        var returnValue = owns(object, name);
 
890
        delete object[name];
 
891
        return returnValue;
 
892
    };
 
893
}
 
894
if (!Object.keys) {
 
895
    var hasDontEnumBug = true,
 
896
        dontEnums = [
 
897
            "toString",
 
898
            "toLocaleString",
 
899
            "valueOf",
 
900
            "hasOwnProperty",
 
901
            "isPrototypeOf",
 
902
            "propertyIsEnumerable",
 
903
            "constructor"
 
904
        ],
 
905
        dontEnumsLength = dontEnums.length;
 
906
 
 
907
    for (var key in {"toString": null}) {
 
908
        hasDontEnumBug = false;
 
909
    }
 
910
 
 
911
    Object.keys = function keys(object) {
 
912
 
 
913
        if (
 
914
            (typeof object != "object" && typeof object != "function") ||
 
915
            object === null
 
916
        ) {
 
917
            throw new TypeError("Object.keys called on a non-object");
 
918
        }
 
919
 
 
920
        var keys = [];
 
921
        for (var name in object) {
 
922
            if (owns(object, name)) {
 
923
                keys.push(name);
 
924
            }
 
925
        }
 
926
 
 
927
        if (hasDontEnumBug) {
 
928
            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
 
929
                var dontEnum = dontEnums[i];
 
930
                if (owns(object, dontEnum)) {
 
931
                    keys.push(dontEnum);
 
932
                }
 
933
            }
 
934
        }
 
935
        return keys;
 
936
    };
 
937
 
 
938
}
 
939
if (!Date.now) {
 
940
    Date.now = function now() {
 
941
        return new Date().getTime();
 
942
    };
 
943
}
 
944
var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
 
945
    "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
 
946
    "\u2029\uFEFF";
 
947
if (!String.prototype.trim || ws.trim()) {
 
948
    ws = "[" + ws + "]";
 
949
    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
 
950
        trimEndRegexp = new RegExp(ws + ws + "*$");
 
951
    String.prototype.trim = function trim() {
 
952
        return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
 
953
    };
 
954
}
 
955
 
 
956
function toInteger(n) {
 
957
    n = +n;
 
958
    if (n !== n) { // isNaN
 
959
        n = 0;
 
960
    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
 
961
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
 
962
    }
 
963
    return n;
 
964
}
 
965
 
 
966
function isPrimitive(input) {
 
967
    var type = typeof input;
 
968
    return (
 
969
        input === null ||
 
970
        type === "undefined" ||
 
971
        type === "boolean" ||
 
972
        type === "number" ||
 
973
        type === "string"
 
974
    );
 
975
}
 
976
 
 
977
function toPrimitive(input) {
 
978
    var val, valueOf, toString;
 
979
    if (isPrimitive(input)) {
 
980
        return input;
 
981
    }
 
982
    valueOf = input.valueOf;
 
983
    if (typeof valueOf === "function") {
 
984
        val = valueOf.call(input);
 
985
        if (isPrimitive(val)) {
 
986
            return val;
 
987
        }
 
988
    }
 
989
    toString = input.toString;
 
990
    if (typeof toString === "function") {
 
991
        val = toString.call(input);
 
992
        if (isPrimitive(val)) {
 
993
            return val;
 
994
        }
 
995
    }
 
996
    throw new TypeError();
 
997
}
 
998
var toObject = function (o) {
 
999
    if (o == null) { // this matches both null and undefined
 
1000
        throw new TypeError("can't convert "+o+" to object");
 
1001
    }
 
1002
    return Object(o);
 
1003
};
 
1004
 
 
1005
});
 
1006
 
 
1007
define('ace/lib/dom', ['require', 'exports', 'module' ], function(require, exports, module) {
 
1008
 
 
1009
 
 
1010
if (typeof document == "undefined")
 
1011
    return;
 
1012
 
 
1013
var XHTML_NS = "http://www.w3.org/1999/xhtml";
 
1014
 
 
1015
exports.getDocumentHead = function(doc) {
 
1016
    if (!doc)
 
1017
        doc = document;
 
1018
    return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
 
1019
}
 
1020
 
 
1021
exports.createElement = function(tag, ns) {
 
1022
    return document.createElementNS ?
 
1023
           document.createElementNS(ns || XHTML_NS, tag) :
 
1024
           document.createElement(tag);
 
1025
};
 
1026
 
 
1027
exports.hasCssClass = function(el, name) {
 
1028
    var classes = el.className.split(/\s+/g);
 
1029
    return classes.indexOf(name) !== -1;
 
1030
};
 
1031
exports.addCssClass = function(el, name) {
 
1032
    if (!exports.hasCssClass(el, name)) {
 
1033
        el.className += " " + name;
 
1034
    }
 
1035
};
 
1036
exports.removeCssClass = function(el, name) {
 
1037
    var classes = el.className.split(/\s+/g);
 
1038
    while (true) {
 
1039
        var index = classes.indexOf(name);
 
1040
        if (index == -1) {
 
1041
            break;
 
1042
        }
 
1043
        classes.splice(index, 1);
 
1044
    }
 
1045
    el.className = classes.join(" ");
 
1046
};
 
1047
 
 
1048
exports.toggleCssClass = function(el, name) {
 
1049
    var classes = el.className.split(/\s+/g), add = true;
 
1050
    while (true) {
 
1051
        var index = classes.indexOf(name);
 
1052
        if (index == -1) {
 
1053
            break;
 
1054
        }
 
1055
        add = false;
 
1056
        classes.splice(index, 1);
 
1057
    }
 
1058
    if(add)
 
1059
        classes.push(name);
 
1060
 
 
1061
    el.className = classes.join(" ");
 
1062
    return add;
 
1063
};
 
1064
exports.setCssClass = function(node, className, include) {
 
1065
    if (include) {
 
1066
        exports.addCssClass(node, className);
 
1067
    } else {
 
1068
        exports.removeCssClass(node, className);
 
1069
    }
 
1070
};
 
1071
 
 
1072
exports.hasCssString = function(id, doc) {
 
1073
    var index = 0, sheets;
 
1074
    doc = doc || document;
 
1075
 
 
1076
    if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
 
1077
        while (index < sheets.length)
 
1078
            if (sheets[index++].owningElement.id === id) return true;
 
1079
    } else if ((sheets = doc.getElementsByTagName("style"))) {
 
1080
        while (index < sheets.length)
 
1081
            if (sheets[index++].id === id) return true;
 
1082
    }
 
1083
 
 
1084
    return false;
 
1085
};
 
1086
 
 
1087
exports.importCssString = function importCssString(cssText, id, doc) {
 
1088
    doc = doc || document;
 
1089
    if (id && exports.hasCssString(id, doc))
 
1090
        return null;
 
1091
    
 
1092
    var style;
 
1093
    
 
1094
    if (doc.createStyleSheet) {
 
1095
        style = doc.createStyleSheet();
 
1096
        style.cssText = cssText;
 
1097
        if (id)
 
1098
            style.owningElement.id = id;
 
1099
    } else {
 
1100
        style = doc.createElementNS
 
1101
            ? doc.createElementNS(XHTML_NS, "style")
 
1102
            : doc.createElement("style");
 
1103
 
 
1104
        style.appendChild(doc.createTextNode(cssText));
 
1105
        if (id)
 
1106
            style.id = id;
 
1107
 
 
1108
        exports.getDocumentHead(doc).appendChild(style);
 
1109
    }
 
1110
};
 
1111
 
 
1112
exports.importCssStylsheet = function(uri, doc) {
 
1113
    if (doc.createStyleSheet) {
 
1114
        doc.createStyleSheet(uri);
 
1115
    } else {
 
1116
        var link = exports.createElement('link');
 
1117
        link.rel = 'stylesheet';
 
1118
        link.href = uri;
 
1119
 
 
1120
        exports.getDocumentHead(doc).appendChild(link);
 
1121
    }
 
1122
};
 
1123
 
 
1124
exports.getInnerWidth = function(element) {
 
1125
    return (
 
1126
        parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
 
1127
        parseInt(exports.computedStyle(element, "paddingRight"), 10) + 
 
1128
        element.clientWidth
 
1129
    );
 
1130
};
 
1131
 
 
1132
exports.getInnerHeight = function(element) {
 
1133
    return (
 
1134
        parseInt(exports.computedStyle(element, "paddingTop"), 10) +
 
1135
        parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
 
1136
        element.clientHeight
 
1137
    );
 
1138
};
 
1139
 
 
1140
if (window.pageYOffset !== undefined) {
 
1141
    exports.getPageScrollTop = function() {
 
1142
        return window.pageYOffset;
 
1143
    };
 
1144
 
 
1145
    exports.getPageScrollLeft = function() {
 
1146
        return window.pageXOffset;
 
1147
    };
 
1148
}
 
1149
else {
 
1150
    exports.getPageScrollTop = function() {
 
1151
        return document.body.scrollTop;
 
1152
    };
 
1153
 
 
1154
    exports.getPageScrollLeft = function() {
 
1155
        return document.body.scrollLeft;
 
1156
    };
 
1157
}
 
1158
 
 
1159
if (window.getComputedStyle)
 
1160
    exports.computedStyle = function(element, style) {
 
1161
        if (style)
 
1162
            return (window.getComputedStyle(element, "") || {})[style] || "";
 
1163
        return window.getComputedStyle(element, "") || {};
 
1164
    };
 
1165
else
 
1166
    exports.computedStyle = function(element, style) {
 
1167
        if (style)
 
1168
            return element.currentStyle[style];
 
1169
        return element.currentStyle;
 
1170
    };
 
1171
 
 
1172
exports.scrollbarWidth = function(document) {
 
1173
    var inner = exports.createElement("ace_inner");
 
1174
    inner.style.width = "100%";
 
1175
    inner.style.minWidth = "0px";
 
1176
    inner.style.height = "200px";
 
1177
    inner.style.display = "block";
 
1178
 
 
1179
    var outer = exports.createElement("ace_outer");
 
1180
    var style = outer.style;
 
1181
 
 
1182
    style.position = "absolute";
 
1183
    style.left = "-10000px";
 
1184
    style.overflow = "hidden";
 
1185
    style.width = "200px";
 
1186
    style.minWidth = "0px";
 
1187
    style.height = "150px";
 
1188
    style.display = "block";
 
1189
 
 
1190
    outer.appendChild(inner);
 
1191
 
 
1192
    var body = document.documentElement;
 
1193
    body.appendChild(outer);
 
1194
 
 
1195
    var noScrollbar = inner.offsetWidth;
 
1196
 
 
1197
    style.overflow = "scroll";
 
1198
    var withScrollbar = inner.offsetWidth;
 
1199
 
 
1200
    if (noScrollbar == withScrollbar) {
 
1201
        withScrollbar = outer.clientWidth;
 
1202
    }
 
1203
 
 
1204
    body.removeChild(outer);
 
1205
 
 
1206
    return noScrollbar-withScrollbar;
 
1207
};
 
1208
exports.setInnerHtml = function(el, innerHtml) {
 
1209
    var element = el.cloneNode(false);//document.createElement("div");
 
1210
    element.innerHTML = innerHtml;
 
1211
    el.parentNode.replaceChild(element, el);
 
1212
    return element;
 
1213
};
 
1214
 
 
1215
if ("textContent" in document.documentElement) {
 
1216
    exports.setInnerText = function(el, innerText) {
 
1217
        el.textContent = innerText;
 
1218
    };
 
1219
 
 
1220
    exports.getInnerText = function(el) {
 
1221
        return el.textContent;
 
1222
    };
 
1223
}
 
1224
else {
 
1225
    exports.setInnerText = function(el, innerText) {
 
1226
        el.innerText = innerText;
 
1227
    };
 
1228
 
 
1229
    exports.getInnerText = function(el) {
 
1230
        return el.innerText;
 
1231
    };
 
1232
}
 
1233
 
 
1234
exports.getParentWindow = function(document) {
 
1235
    return document.defaultView || document.parentWindow;
 
1236
};
 
1237
 
 
1238
});
 
1239
 
 
1240
define('ace/lib/event', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/useragent', 'ace/lib/dom'], function(require, exports, module) {
 
1241
 
 
1242
 
 
1243
var keys = require("./keys");
 
1244
var useragent = require("./useragent");
 
1245
var dom = require("./dom");
 
1246
 
 
1247
exports.addListener = function(elem, type, callback) {
 
1248
    if (elem.addEventListener) {
 
1249
        return elem.addEventListener(type, callback, false);
 
1250
    }
 
1251
    if (elem.attachEvent) {
 
1252
        var wrapper = function() {
 
1253
            callback(window.event);
 
1254
        };
 
1255
        callback._wrapper = wrapper;
 
1256
        elem.attachEvent("on" + type, wrapper);
 
1257
    }
 
1258
};
 
1259
 
 
1260
exports.removeListener = function(elem, type, callback) {
 
1261
    if (elem.removeEventListener) {
 
1262
        return elem.removeEventListener(type, callback, false);
 
1263
    }
 
1264
    if (elem.detachEvent) {
 
1265
        elem.detachEvent("on" + type, callback._wrapper || callback);
 
1266
    }
 
1267
};
 
1268
exports.stopEvent = function(e) {
 
1269
    exports.stopPropagation(e);
 
1270
    exports.preventDefault(e);
 
1271
    return false;
 
1272
};
 
1273
 
 
1274
exports.stopPropagation = function(e) {
 
1275
    if (e.stopPropagation)
 
1276
        e.stopPropagation();
 
1277
    else
 
1278
        e.cancelBubble = true;
 
1279
};
 
1280
 
 
1281
exports.preventDefault = function(e) {
 
1282
    if (e.preventDefault)
 
1283
        e.preventDefault();
 
1284
    else
 
1285
        e.returnValue = false;
 
1286
};
 
1287
exports.getButton = function(e) {
 
1288
    if (e.type == "dblclick")
 
1289
        return 0;
 
1290
    if (e.type == "contextmenu" || (e.ctrlKey && useragent.isMac))
 
1291
        return 2;
 
1292
    if (e.preventDefault) {
 
1293
        return e.button;
 
1294
    }
 
1295
    else {
 
1296
        return {1:0, 2:2, 4:1}[e.button];
 
1297
    }
 
1298
};
 
1299
 
 
1300
if (document.documentElement.setCapture) {
 
1301
    exports.capture = function(el, eventHandler, releaseCaptureHandler) {
 
1302
        var called = false;
 
1303
        function onReleaseCapture(e) {
 
1304
            eventHandler(e);
 
1305
 
 
1306
            if (!called) {
 
1307
                called = true;
 
1308
                releaseCaptureHandler(e);
 
1309
            }
 
1310
 
 
1311
            exports.removeListener(el, "mousemove", eventHandler);
 
1312
            exports.removeListener(el, "mouseup", onReleaseCapture);
 
1313
            exports.removeListener(el, "losecapture", onReleaseCapture);
 
1314
 
 
1315
            el.releaseCapture();
 
1316
        }
 
1317
 
 
1318
        exports.addListener(el, "mousemove", eventHandler);
 
1319
        exports.addListener(el, "mouseup", onReleaseCapture);
 
1320
        exports.addListener(el, "losecapture", onReleaseCapture);
 
1321
        el.setCapture();
 
1322
    };
 
1323
}
 
1324
else {
 
1325
    exports.capture = function(el, eventHandler, releaseCaptureHandler) {
 
1326
        function onMouseUp(e) {
 
1327
            eventHandler && eventHandler(e);
 
1328
            releaseCaptureHandler && releaseCaptureHandler(e);
 
1329
 
 
1330
            document.removeEventListener("mousemove", eventHandler, true);
 
1331
            document.removeEventListener("mouseup", onMouseUp, true);
 
1332
 
 
1333
            e.stopPropagation();
 
1334
        }
 
1335
 
 
1336
        document.addEventListener("mousemove", eventHandler, true);
 
1337
        document.addEventListener("mouseup", onMouseUp, true);
 
1338
    };
 
1339
}
 
1340
 
 
1341
exports.addMouseWheelListener = function(el, callback) {
 
1342
    var factor = 8;
 
1343
    var listener = function(e) {
 
1344
        if (e.wheelDelta !== undefined) {
 
1345
            if (e.wheelDeltaX !== undefined) {
 
1346
                e.wheelX = -e.wheelDeltaX / factor;
 
1347
                e.wheelY = -e.wheelDeltaY / factor;
 
1348
            } else {
 
1349
                e.wheelX = 0;
 
1350
                e.wheelY = -e.wheelDelta / factor;
 
1351
            }
 
1352
        }
 
1353
        else {
 
1354
            if (e.axis && e.axis == e.HORIZONTAL_AXIS) {
 
1355
                e.wheelX = (e.detail || 0) * 5;
 
1356
                e.wheelY = 0;
 
1357
            } else {
 
1358
                e.wheelX = 0;
 
1359
                e.wheelY = (e.detail || 0) * 5;
 
1360
            }
 
1361
        }
 
1362
        callback(e);
 
1363
    };
 
1364
    exports.addListener(el, "DOMMouseScroll", listener);
 
1365
    exports.addListener(el, "mousewheel", listener);
 
1366
};
 
1367
 
 
1368
exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbackName) {
 
1369
    var clicks = 0;
 
1370
    var startX, startY, timer;
 
1371
    var eventNames = {
 
1372
        2: "dblclick",
 
1373
        3: "tripleclick",
 
1374
        4: "quadclick"
 
1375
    };
 
1376
 
 
1377
    exports.addListener(el, "mousedown", function(e) {
 
1378
        if (exports.getButton(e) != 0) {
 
1379
            clicks = 0;
 
1380
        } else {
 
1381
            var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;
 
1382
 
 
1383
            if (!timer || isNewClick)
 
1384
                clicks = 0;
 
1385
 
 
1386
            clicks += 1;
 
1387
 
 
1388
            if (timer)
 
1389
                clearTimeout(timer)
 
1390
            timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
 
1391
        }
 
1392
        if (clicks == 1) {
 
1393
            startX = e.clientX;
 
1394
            startY = e.clientY;
 
1395
        }
 
1396
 
 
1397
        eventHandler[callbackName]("mousedown", e);
 
1398
 
 
1399
        if (clicks > 4)
 
1400
            clicks = 0;
 
1401
        else if (clicks > 1)
 
1402
            return eventHandler[callbackName](eventNames[clicks], e);
 
1403
    });
 
1404
 
 
1405
    if (useragent.isOldIE) {
 
1406
        exports.addListener(el, "dblclick", function(e) {
 
1407
            clicks = 2;
 
1408
            if (timer)
 
1409
                clearTimeout(timer);
 
1410
            timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
 
1411
            eventHandler[callbackName]("mousedown", e);
 
1412
            eventHandler[callbackName](eventNames[clicks], e);
 
1413
        });
 
1414
    }
 
1415
};
 
1416
 
 
1417
function normalizeCommandKeys(callback, e, keyCode) {
 
1418
    var hashId = 0;
 
1419
    if ((useragent.isOpera && !("KeyboardEvent" in window)) && useragent.isMac) {
 
1420
        hashId = 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0)
 
1421
            | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
 
1422
    } else {
 
1423
        hashId = 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0)
 
1424
            | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
 
1425
    }
 
1426
 
 
1427
    if (keyCode in keys.MODIFIER_KEYS) {
 
1428
        switch (keys.MODIFIER_KEYS[keyCode]) {
 
1429
            case "Alt":
 
1430
                hashId = 2;
 
1431
                break;
 
1432
            case "Shift":
 
1433
                hashId = 4;
 
1434
                break;
 
1435
            case "Ctrl":
 
1436
                hashId = 1;
 
1437
                break;
 
1438
            default:
 
1439
                hashId = 8;
 
1440
                break;
 
1441
        }
 
1442
        keyCode = 0;
 
1443
    }
 
1444
 
 
1445
    if (hashId & 8 && (keyCode == 91 || keyCode == 93)) {
 
1446
        keyCode = 0;
 
1447
    }
 
1448
    if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {
 
1449
        return false;
 
1450
    }
 
1451
    return callback(e, hashId, keyCode);
 
1452
}
 
1453
 
 
1454
exports.addCommandKeyListener = function(el, callback) {
 
1455
    var addListener = exports.addListener;
 
1456
    if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) {
 
1457
        var lastKeyDownKeyCode = null;
 
1458
        addListener(el, "keydown", function(e) {
 
1459
            lastKeyDownKeyCode = e.keyCode;
 
1460
        });
 
1461
        addListener(el, "keypress", function(e) {
 
1462
            return normalizeCommandKeys(callback, e, lastKeyDownKeyCode);
 
1463
        });
 
1464
    } else {
 
1465
        var lastDown = null;
 
1466
 
 
1467
        addListener(el, "keydown", function(e) {
 
1468
            lastDown = e.keyIdentifier || e.keyCode;
 
1469
            return normalizeCommandKeys(callback, e, e.keyCode);
 
1470
        });
 
1471
    }
 
1472
};
 
1473
 
 
1474
if (window.postMessage && !useragent.isOldIE) {
 
1475
    var postMessageId = 1;
 
1476
    exports.nextTick = function(callback, win) {
 
1477
        win = win || window;
 
1478
        var messageName = "zero-timeout-message-" + postMessageId;
 
1479
        exports.addListener(win, "message", function listener(e) {
 
1480
            if (e.data == messageName) {
 
1481
                exports.stopPropagation(e);
 
1482
                exports.removeListener(win, "message", listener);
 
1483
                callback();
 
1484
            }
 
1485
        });
 
1486
        win.postMessage(messageName, "*");
 
1487
    };
 
1488
}
 
1489
 
 
1490
 
 
1491
exports.nextFrame = window.requestAnimationFrame ||
 
1492
    window.mozRequestAnimationFrame ||
 
1493
    window.webkitRequestAnimationFrame ||
 
1494
    window.msRequestAnimationFrame ||
 
1495
    window.oRequestAnimationFrame;
 
1496
 
 
1497
if (exports.nextFrame)
 
1498
    exports.nextFrame = exports.nextFrame.bind(window);
 
1499
else
 
1500
    exports.nextFrame = function(callback) {
 
1501
        setTimeout(callback, 17);
 
1502
    };
 
1503
});
 
1504
 
 
1505
define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/lib/oop'], function(require, exports, module) {
 
1506
 
 
1507
 
 
1508
var oop = require("./oop");
 
1509
var Keys = (function() {
 
1510
    var ret = {
 
1511
        MODIFIER_KEYS: {
 
1512
            16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
 
1513
        },
 
1514
 
 
1515
        KEY_MODS: {
 
1516
            "ctrl": 1, "alt": 2, "option" : 2,
 
1517
            "shift": 4, "meta": 8, "command": 8
 
1518
        },
 
1519
 
 
1520
        FUNCTION_KEYS : {
 
1521
            8  : "Backspace",
 
1522
            9  : "Tab",
 
1523
            13 : "Return",
 
1524
            19 : "Pause",
 
1525
            27 : "Esc",
 
1526
            32 : "Space",
 
1527
            33 : "PageUp",
 
1528
            34 : "PageDown",
 
1529
            35 : "End",
 
1530
            36 : "Home",
 
1531
            37 : "Left",
 
1532
            38 : "Up",
 
1533
            39 : "Right",
 
1534
            40 : "Down",
 
1535
            44 : "Print",
 
1536
            45 : "Insert",
 
1537
            46 : "Delete",
 
1538
            96 : "Numpad0",
 
1539
            97 : "Numpad1",
 
1540
            98 : "Numpad2",
 
1541
            99 : "Numpad3",
 
1542
            100: "Numpad4",
 
1543
            101: "Numpad5",
 
1544
            102: "Numpad6",
 
1545
            103: "Numpad7",
 
1546
            104: "Numpad8",
 
1547
            105: "Numpad9",
 
1548
            112: "F1",
 
1549
            113: "F2",
 
1550
            114: "F3",
 
1551
            115: "F4",
 
1552
            116: "F5",
 
1553
            117: "F6",
 
1554
            118: "F7",
 
1555
            119: "F8",
 
1556
            120: "F9",
 
1557
            121: "F10",
 
1558
            122: "F11",
 
1559
            123: "F12",
 
1560
            144: "Numlock",
 
1561
            145: "Scrolllock"
 
1562
        },
 
1563
 
 
1564
        PRINTABLE_KEYS: {
 
1565
           32: ' ',  48: '0',  49: '1',  50: '2',  51: '3',  52: '4', 53:  '5',
 
1566
           54: '6',  55: '7',  56: '8',  57: '9',  59: ';',  61: '=', 65:  'a',
 
1567
           66: 'b',  67: 'c',  68: 'd',  69: 'e',  70: 'f',  71: 'g', 72:  'h',
 
1568
           73: 'i',  74: 'j',  75: 'k',  76: 'l',  77: 'm',  78: 'n', 79:  'o',
 
1569
           80: 'p',  81: 'q',  82: 'r',  83: 's',  84: 't',  85: 'u', 86:  'v',
 
1570
           87: 'w',  88: 'x',  89: 'y',  90: 'z', 107: '+', 109: '-', 110: '.',
 
1571
          188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
 
1572
          221: ']', 222: '\''
 
1573
        }
 
1574
    };
 
1575
    for (var i in ret.FUNCTION_KEYS) {
 
1576
        var name = ret.FUNCTION_KEYS[i].toLowerCase();
 
1577
        ret[name] = parseInt(i, 10);
 
1578
    }
 
1579
    oop.mixin(ret, ret.MODIFIER_KEYS);
 
1580
    oop.mixin(ret, ret.PRINTABLE_KEYS);
 
1581
    oop.mixin(ret, ret.FUNCTION_KEYS);
 
1582
    ret.enter = ret["return"];
 
1583
    ret.escape = ret.esc;
 
1584
    ret.del = ret["delete"];
 
1585
    ret[173] = '-';
 
1586
 
 
1587
    return ret;
 
1588
})();
 
1589
oop.mixin(exports, Keys);
 
1590
 
 
1591
exports.keyCodeToString = function(keyCode) {
 
1592
    return (Keys[keyCode] || String.fromCharCode(keyCode)).toLowerCase();
 
1593
}
 
1594
 
 
1595
});
 
1596
 
 
1597
define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
 
1598
 
 
1599
 
 
1600
exports.inherits = (function() {
 
1601
    var tempCtor = function() {};
 
1602
    return function(ctor, superCtor) {
 
1603
        tempCtor.prototype = superCtor.prototype;
 
1604
        ctor.super_ = superCtor.prototype;
 
1605
        ctor.prototype = new tempCtor();
 
1606
        ctor.prototype.constructor = ctor;
 
1607
    };
 
1608
}());
 
1609
 
 
1610
exports.mixin = function(obj, mixin) {
 
1611
    for (var key in mixin) {
 
1612
        obj[key] = mixin[key];
 
1613
    }
 
1614
};
 
1615
 
 
1616
exports.implement = function(proto, mixin) {
 
1617
    exports.mixin(proto, mixin);
 
1618
};
 
1619
 
 
1620
});
 
1621
 
 
1622
define('ace/lib/useragent', ['require', 'exports', 'module' ], function(require, exports, module) {
 
1623
exports.OS = {
 
1624
    LINUX: "LINUX",
 
1625
    MAC: "MAC",
 
1626
    WINDOWS: "WINDOWS"
 
1627
};
 
1628
exports.getOS = function() {
 
1629
    if (exports.isMac) {
 
1630
        return exports.OS.MAC;
 
1631
    } else if (exports.isLinux) {
 
1632
        return exports.OS.LINUX;
 
1633
    } else {
 
1634
        return exports.OS.WINDOWS;
 
1635
    }
 
1636
};
 
1637
if (typeof navigator != "object")
 
1638
    return;
 
1639
 
 
1640
var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
 
1641
var ua = navigator.userAgent;
 
1642
exports.isWin = (os == "win");
 
1643
exports.isMac = (os == "mac");
 
1644
exports.isLinux = (os == "linux");
 
1645
exports.isIE = 
 
1646
    (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
 
1647
    && parseFloat(navigator.userAgent.match(/MSIE ([0-9]+[\.0-9]+)/)[1]);
 
1648
    
 
1649
exports.isOldIE = exports.isIE && exports.isIE < 9;
 
1650
exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko";
 
1651
exports.isOldGecko = exports.isGecko && parseInt((navigator.userAgent.match(/rv\:(\d+)/)||[])[1], 10) < 4;
 
1652
exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
 
1653
exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
 
1654
 
 
1655
exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
 
1656
 
 
1657
exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
 
1658
 
 
1659
exports.isIPad = ua.indexOf("iPad") >= 0;
 
1660
 
 
1661
exports.isTouchPad = ua.indexOf("TouchPad") >= 0;
 
1662
 
 
1663
});
 
1664
 
 
1665
define('ace/editor', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/oop', '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'], function(require, exports, module) {
 
1666
 
 
1667
 
 
1668
require("./lib/fixoldbrowsers");
 
1669
 
 
1670
var oop = require("./lib/oop");
 
1671
var lang = require("./lib/lang");
 
1672
var useragent = require("./lib/useragent");
 
1673
var TextInput = require("./keyboard/textinput").TextInput;
 
1674
var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
 
1675
var FoldHandler = require("./mouse/fold_handler").FoldHandler;
 
1676
var KeyBinding = require("./keyboard/keybinding").KeyBinding;
 
1677
var EditSession = require("./edit_session").EditSession;
 
1678
var Search = require("./search").Search;
 
1679
var Range = require("./range").Range;
 
1680
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
1681
var CommandManager = require("./commands/command_manager").CommandManager;
 
1682
var defaultCommands = require("./commands/default_commands").commands;
 
1683
var config = require("./config");
 
1684
var Editor = function(renderer, session) {
 
1685
    var container = renderer.getContainerElement();
 
1686
    this.container = container;
 
1687
    this.renderer = renderer;
 
1688
 
 
1689
    this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
 
1690
    this.textInput  = new TextInput(renderer.getTextAreaContainer(), this);
 
1691
    this.renderer.textarea = this.textInput.getElement();
 
1692
    this.keyBinding = new KeyBinding(this);
 
1693
    this.$mouseHandler = new MouseHandler(this);
 
1694
    new FoldHandler(this);
 
1695
 
 
1696
    this.$blockScrolling = 0;
 
1697
    this.$search = new Search().set({
 
1698
        wrap: true
 
1699
    });
 
1700
 
 
1701
    this.setSession(session || new EditSession(""));
 
1702
    config.resetOptions(this);
 
1703
    config._emit("editor", this);
 
1704
};
 
1705
 
 
1706
(function(){
 
1707
 
 
1708
    oop.implement(this, EventEmitter);
 
1709
    this.setKeyboardHandler = function(keyboardHandler) {
 
1710
        if (typeof keyboardHandler == "string" && keyboardHandler) {
 
1711
            this.$keybindingId = keyboardHandler;
 
1712
            var _self = this;
 
1713
            config.loadModule(["keybinding", keyboardHandler], function(module) {
 
1714
                if (_self.$keybindingId == keyboardHandler)
 
1715
                    _self.keyBinding.setKeyboardHandler(module && module.handler);
 
1716
            });
 
1717
        } else {
 
1718
            delete this.$keybindingId;
 
1719
            this.keyBinding.setKeyboardHandler(keyboardHandler);
 
1720
        }
 
1721
    };
 
1722
    this.getKeyboardHandler = function() {
 
1723
        return this.keyBinding.getKeyboardHandler();
 
1724
    };
 
1725
    this.setSession = function(session) {
 
1726
        if (this.session == session)
 
1727
            return;
 
1728
 
 
1729
        if (this.session) {
 
1730
            var oldSession = this.session;
 
1731
            this.session.removeEventListener("change", this.$onDocumentChange);
 
1732
            this.session.removeEventListener("changeMode", this.$onChangeMode);
 
1733
            this.session.removeEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
 
1734
            this.session.removeEventListener("changeTabSize", this.$onChangeTabSize);
 
1735
            this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit);
 
1736
            this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode);
 
1737
            this.session.removeEventListener("onChangeFold", this.$onChangeFold);
 
1738
            this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker);
 
1739
            this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker);
 
1740
            this.session.removeEventListener("changeBreakpoint", this.$onChangeBreakpoint);
 
1741
            this.session.removeEventListener("changeAnnotation", this.$onChangeAnnotation);
 
1742
            this.session.removeEventListener("changeOverwrite", this.$onCursorChange);
 
1743
            this.session.removeEventListener("changeScrollTop", this.$onScrollTopChange);
 
1744
            this.session.removeEventListener("changeLeftTop", this.$onScrollLeftChange);
 
1745
 
 
1746
            var selection = this.session.getSelection();
 
1747
            selection.removeEventListener("changeCursor", this.$onCursorChange);
 
1748
            selection.removeEventListener("changeSelection", this.$onSelectionChange);
 
1749
        }
 
1750
 
 
1751
        this.session = session;
 
1752
 
 
1753
        this.$onDocumentChange = this.onDocumentChange.bind(this);
 
1754
        session.addEventListener("change", this.$onDocumentChange);
 
1755
        this.renderer.setSession(session);
 
1756
 
 
1757
        this.$onChangeMode = this.onChangeMode.bind(this);
 
1758
        session.addEventListener("changeMode", this.$onChangeMode);
 
1759
 
 
1760
        this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
 
1761
        session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
 
1762
 
 
1763
        this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
 
1764
        session.addEventListener("changeTabSize", this.$onChangeTabSize);
 
1765
 
 
1766
        this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
 
1767
        session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit);
 
1768
 
 
1769
        this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
 
1770
        session.addEventListener("changeWrapMode", this.$onChangeWrapMode);
 
1771
 
 
1772
        this.$onChangeFold = this.onChangeFold.bind(this);
 
1773
        session.addEventListener("changeFold", this.$onChangeFold);
 
1774
 
 
1775
        this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
 
1776
        this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker);
 
1777
 
 
1778
        this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
 
1779
        this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker);
 
1780
 
 
1781
        this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
 
1782
        this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint);
 
1783
 
 
1784
        this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
 
1785
        this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation);
 
1786
 
 
1787
        this.$onCursorChange = this.onCursorChange.bind(this);
 
1788
        this.session.addEventListener("changeOverwrite", this.$onCursorChange);
 
1789
 
 
1790
        this.$onScrollTopChange = this.onScrollTopChange.bind(this);
 
1791
        this.session.addEventListener("changeScrollTop", this.$onScrollTopChange);
 
1792
 
 
1793
        this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
 
1794
        this.session.addEventListener("changeScrollLeft", this.$onScrollLeftChange);
 
1795
 
 
1796
        this.selection = session.getSelection();
 
1797
        this.selection.addEventListener("changeCursor", this.$onCursorChange);
 
1798
 
 
1799
        this.$onSelectionChange = this.onSelectionChange.bind(this);
 
1800
        this.selection.addEventListener("changeSelection", this.$onSelectionChange);
 
1801
 
 
1802
        this.onChangeMode();
 
1803
 
 
1804
        this.$blockScrolling += 1;
 
1805
        this.onCursorChange();
 
1806
        this.$blockScrolling -= 1;
 
1807
 
 
1808
        this.onScrollTopChange();
 
1809
        this.onScrollLeftChange();
 
1810
        this.onSelectionChange();
 
1811
        this.onChangeFrontMarker();
 
1812
        this.onChangeBackMarker();
 
1813
        this.onChangeBreakpoint();
 
1814
        this.onChangeAnnotation();
 
1815
        this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
 
1816
        this.renderer.updateFull();
 
1817
 
 
1818
        this._emit("changeSession", {
 
1819
            session: session,
 
1820
            oldSession: oldSession
 
1821
        });
 
1822
    };
 
1823
    this.getSession = function() {
 
1824
        return this.session;
 
1825
    };
 
1826
    this.setValue = function(val, cursorPos) {
 
1827
        this.session.doc.setValue(val);
 
1828
 
 
1829
        if (!cursorPos)
 
1830
            this.selectAll();
 
1831
        else if (cursorPos == 1)
 
1832
            this.navigateFileEnd();
 
1833
        else if (cursorPos == -1)
 
1834
            this.navigateFileStart();
 
1835
 
 
1836
        return val;
 
1837
    };
 
1838
    this.getValue = function() {
 
1839
        return this.session.getValue();
 
1840
    };
 
1841
    this.getSelection = function() {
 
1842
        return this.selection;
 
1843
    };
 
1844
    this.resize = function(force) {
 
1845
        this.renderer.onResize(force);
 
1846
    };
 
1847
    this.setTheme = function(theme) {
 
1848
        this.renderer.setTheme(theme);
 
1849
    };
 
1850
    this.getTheme = function() {
 
1851
        return this.renderer.getTheme();
 
1852
    };
 
1853
    this.setStyle = function(style) {
 
1854
        this.renderer.setStyle(style);
 
1855
    };
 
1856
    this.unsetStyle = function(style) {
 
1857
        this.renderer.unsetStyle(style);
 
1858
    };
 
1859
    this.setFontSize = function(size) {
 
1860
        if (typeof size == "number")
 
1861
            size = size + "px";
 
1862
        this.container.style.fontSize = size;
 
1863
        this.renderer.updateFontSize();
 
1864
    };
 
1865
 
 
1866
    this.$highlightBrackets = function() {
 
1867
        if (this.session.$bracketHighlight) {
 
1868
            this.session.removeMarker(this.session.$bracketHighlight);
 
1869
            this.session.$bracketHighlight = null;
 
1870
        }
 
1871
 
 
1872
        if (this.$highlightPending) {
 
1873
            return;
 
1874
        }
 
1875
        var self = this;
 
1876
        this.$highlightPending = true;
 
1877
        setTimeout(function() {
 
1878
            self.$highlightPending = false;
 
1879
 
 
1880
            var pos = self.session.findMatchingBracket(self.getCursorPosition());
 
1881
            if (pos) {
 
1882
                var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
 
1883
            } else if (self.session.$mode.getMatching) {
 
1884
                var range = self.session.$mode.getMatching(self.session);
 
1885
            }
 
1886
            if (range)
 
1887
                self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text");
 
1888
        }, 50);
 
1889
    };
 
1890
    this.focus = function() {
 
1891
        var _self = this;
 
1892
        setTimeout(function() {
 
1893
            _self.textInput.focus();
 
1894
        });
 
1895
        this.textInput.focus();
 
1896
    };
 
1897
    this.isFocused = function() {
 
1898
        return this.textInput.isFocused();
 
1899
    };
 
1900
    this.blur = function() {
 
1901
        this.textInput.blur();
 
1902
    };
 
1903
    this.onFocus = function() {
 
1904
        if (this.$isFocused)
 
1905
            return;
 
1906
        this.$isFocused = true;
 
1907
        this.renderer.showCursor();
 
1908
        this.renderer.visualizeFocus();
 
1909
        this._emit("focus");
 
1910
    };
 
1911
    this.onBlur = function() {
 
1912
        if (!this.$isFocused)
 
1913
            return;
 
1914
        this.$isFocused = false;
 
1915
        this.renderer.hideCursor();
 
1916
        this.renderer.visualizeBlur();
 
1917
        this._emit("blur");
 
1918
    };
 
1919
 
 
1920
    this.$cursorChange = function() {
 
1921
        this.renderer.updateCursor();
 
1922
    };
 
1923
    this.onDocumentChange = function(e) {
 
1924
        var delta = e.data;
 
1925
        var range = delta.range;
 
1926
        var lastRow;
 
1927
 
 
1928
        if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines")
 
1929
            lastRow = range.end.row;
 
1930
        else
 
1931
            lastRow = Infinity;
 
1932
        this.renderer.updateLines(range.start.row, lastRow);
 
1933
 
 
1934
        this._emit("change", e);
 
1935
        this.$cursorChange();
 
1936
    };
 
1937
 
 
1938
    this.onTokenizerUpdate = function(e) {
 
1939
        var rows = e.data;
 
1940
        this.renderer.updateLines(rows.first, rows.last);
 
1941
    };
 
1942
 
 
1943
 
 
1944
    this.onScrollTopChange = function() {
 
1945
        this.renderer.scrollToY(this.session.getScrollTop());
 
1946
    };
 
1947
 
 
1948
    this.onScrollLeftChange = function() {
 
1949
        this.renderer.scrollToX(this.session.getScrollLeft());
 
1950
    };
 
1951
    this.onCursorChange = function() {
 
1952
        this.$cursorChange();
 
1953
 
 
1954
        if (!this.$blockScrolling) {
 
1955
            this.renderer.scrollCursorIntoView();
 
1956
        }
 
1957
 
 
1958
        this.$highlightBrackets();
 
1959
        this.$updateHighlightActiveLine();
 
1960
        this._emit("changeSelection");
 
1961
    };
 
1962
 
 
1963
    this.$updateHighlightActiveLine = function() {
 
1964
        var session = this.getSession();
 
1965
 
 
1966
        var highlight;
 
1967
        if (this.$highlightActiveLine) {
 
1968
            if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
 
1969
                highlight = this.getCursorPosition();
 
1970
        }
 
1971
 
 
1972
        if (session.$highlightLineMarker && !highlight) {
 
1973
            session.removeMarker(session.$highlightLineMarker.id);
 
1974
            session.$highlightLineMarker = null;
 
1975
        } else if (!session.$highlightLineMarker && highlight) {
 
1976
            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
 
1977
            range.id = session.addMarker(range, "ace_active-line", "screenLine");
 
1978
            session.$highlightLineMarker = range;
 
1979
        } else if (highlight) {
 
1980
            session.$highlightLineMarker.start.row = highlight.row;
 
1981
            session.$highlightLineMarker.end.row = highlight.row;
 
1982
            session.$highlightLineMarker.start.column = highlight.column;
 
1983
            session._emit("changeBackMarker");
 
1984
        }
 
1985
    };
 
1986
 
 
1987
    this.onSelectionChange = function(e) {
 
1988
        var session = this.session;
 
1989
 
 
1990
        if (session.$selectionMarker) {
 
1991
            session.removeMarker(session.$selectionMarker);
 
1992
        }
 
1993
        session.$selectionMarker = null;
 
1994
 
 
1995
        if (!this.selection.isEmpty()) {
 
1996
            var range = this.selection.getRange();
 
1997
            var style = this.getSelectionStyle();
 
1998
            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
 
1999
        } else {
 
2000
            this.$updateHighlightActiveLine();
 
2001
        }
 
2002
 
 
2003
        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
 
2004
        this.session.highlight(re);
 
2005
 
 
2006
        this._emit("changeSelection");
 
2007
    };
 
2008
 
 
2009
    this.$getSelectionHighLightRegexp = function() {
 
2010
        var session = this.session;
 
2011
 
 
2012
        var selection = this.getSelectionRange();
 
2013
        if (selection.isEmpty() || selection.isMultiLine())
 
2014
            return;
 
2015
 
 
2016
        var startOuter = selection.start.column - 1;
 
2017
        var endOuter = selection.end.column + 1;
 
2018
        var line = session.getLine(selection.start.row);
 
2019
        var lineCols = line.length;
 
2020
        var needle = line.substring(Math.max(startOuter, 0),
 
2021
                                    Math.min(endOuter, lineCols));
 
2022
        if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
 
2023
            (endOuter <= lineCols && /[\w\d]$/.test(needle)))
 
2024
            return;
 
2025
 
 
2026
        needle = line.substring(selection.start.column, selection.end.column);
 
2027
        if (!/^[\w\d]+$/.test(needle))
 
2028
            return;
 
2029
 
 
2030
        var re = this.$search.$assembleRegExp({
 
2031
            wholeWord: true,
 
2032
            caseSensitive: true,
 
2033
            needle: needle
 
2034
        });
 
2035
 
 
2036
        return re;
 
2037
    };
 
2038
 
 
2039
 
 
2040
    this.onChangeFrontMarker = function() {
 
2041
        this.renderer.updateFrontMarkers();
 
2042
    };
 
2043
 
 
2044
    this.onChangeBackMarker = function() {
 
2045
        this.renderer.updateBackMarkers();
 
2046
    };
 
2047
 
 
2048
 
 
2049
    this.onChangeBreakpoint = function() {
 
2050
        this.renderer.updateBreakpoints();
 
2051
    };
 
2052
 
 
2053
    this.onChangeAnnotation = function() {
 
2054
        this.renderer.setAnnotations(this.session.getAnnotations());
 
2055
    };
 
2056
 
 
2057
 
 
2058
    this.onChangeMode = function(e) {
 
2059
        this.renderer.updateText();
 
2060
        this._emit("changeMode", e);
 
2061
    };
 
2062
 
 
2063
 
 
2064
    this.onChangeWrapLimit = function() {
 
2065
        this.renderer.updateFull();
 
2066
    };
 
2067
 
 
2068
    this.onChangeWrapMode = function() {
 
2069
        this.renderer.onResize(true);
 
2070
    };
 
2071
 
 
2072
 
 
2073
    this.onChangeFold = function() {
 
2074
        this.$updateHighlightActiveLine();
 
2075
        this.renderer.updateFull();
 
2076
    };
 
2077
 
 
2078
    this.getCopyText = function() {
 
2079
        var text = "";
 
2080
        if (!this.selection.isEmpty())
 
2081
            text = this.session.getTextRange(this.getSelectionRange());
 
2082
 
 
2083
        this._emit("copy", text);
 
2084
        return text;
 
2085
    };
 
2086
    this.onCopy = function() {
 
2087
        this.commands.exec("copy", this);
 
2088
    };
 
2089
    this.onCut = function() {
 
2090
        this.commands.exec("cut", this);
 
2091
    };
 
2092
    this.onPaste = function(text) {
 
2093
        if (this.$readOnly)
 
2094
            return;
 
2095
        this._emit("paste", text);
 
2096
        this.insert(text);
 
2097
    };
 
2098
 
 
2099
 
 
2100
    this.execCommand = function(command, args) {
 
2101
        this.commands.exec(command, this, args);
 
2102
    };
 
2103
    this.insert = function(text) {
 
2104
        var session = this.session;
 
2105
        var mode = session.getMode();
 
2106
        var cursor = this.getCursorPosition();
 
2107
 
 
2108
        if (this.getBehavioursEnabled()) {
 
2109
            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
 
2110
            if (transform)
 
2111
                text = transform.text;
 
2112
        }
 
2113
 
 
2114
        text = text.replace("\t", this.session.getTabString());
 
2115
        if (!this.selection.isEmpty()) {
 
2116
            cursor = this.session.remove(this.getSelectionRange());
 
2117
            this.clearSelection();
 
2118
        }
 
2119
        else if (this.session.getOverwrite()) {
 
2120
            var range = new Range.fromPoints(cursor, cursor);
 
2121
            range.end.column += text.length;
 
2122
            this.session.remove(range);
 
2123
        }
 
2124
 
 
2125
        this.clearSelection();
 
2126
 
 
2127
        var start = cursor.column;
 
2128
        var lineState = session.getState(cursor.row);
 
2129
        var line = session.getLine(cursor.row);
 
2130
        var shouldOutdent = mode.checkOutdent(lineState, line, text);
 
2131
        var end = session.insert(cursor, text);
 
2132
 
 
2133
        if (transform && transform.selection) {
 
2134
            if (transform.selection.length == 2) { // Transform relative to the current column
 
2135
                this.selection.setSelectionRange(
 
2136
                    new Range(cursor.row, start + transform.selection[0],
 
2137
                              cursor.row, start + transform.selection[1]));
 
2138
            } else { // Transform relative to the current row.
 
2139
                this.selection.setSelectionRange(
 
2140
                    new Range(cursor.row + transform.selection[0],
 
2141
                              transform.selection[1],
 
2142
                              cursor.row + transform.selection[2],
 
2143
                              transform.selection[3]));
 
2144
            }
 
2145
        }
 
2146
        if (session.getDocument().isNewLine(text)) {
 
2147
            var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
 
2148
 
 
2149
            this.moveCursorTo(cursor.row+1, 0);
 
2150
 
 
2151
            var size = session.getTabSize();
 
2152
            var minIndent = Number.MAX_VALUE;
 
2153
 
 
2154
            for (var row = cursor.row + 1; row <= end.row; ++row) {
 
2155
                var indent = 0;
 
2156
 
 
2157
                line = session.getLine(row);
 
2158
                for (var i = 0; i < line.length; ++i)
 
2159
                    if (line.charAt(i) == '\t')
 
2160
                        indent += size;
 
2161
                    else if (line.charAt(i) == ' ')
 
2162
                        indent += 1;
 
2163
                    else
 
2164
                        break;
 
2165
                if (/[^\s]/.test(line))
 
2166
                    minIndent = Math.min(indent, minIndent);
 
2167
            }
 
2168
 
 
2169
            for (var row = cursor.row + 1; row <= end.row; ++row) {
 
2170
                var outdent = minIndent;
 
2171
 
 
2172
                line = session.getLine(row);
 
2173
                for (var i = 0; i < line.length && outdent > 0; ++i)
 
2174
                    if (line.charAt(i) == '\t')
 
2175
                        outdent -= size;
 
2176
                    else if (line.charAt(i) == ' ')
 
2177
                        outdent -= 1;
 
2178
                session.remove(new Range(row, 0, row, i));
 
2179
            }
 
2180
            session.indentRows(cursor.row + 1, end.row, lineIndent);
 
2181
        }
 
2182
        if (shouldOutdent)
 
2183
            mode.autoOutdent(lineState, session, cursor.row);
 
2184
    };
 
2185
 
 
2186
    this.onTextInput = function(text) {
 
2187
        this.keyBinding.onTextInput(text);
 
2188
    };
 
2189
 
 
2190
    this.onCommandKey = function(e, hashId, keyCode) {
 
2191
        this.keyBinding.onCommandKey(e, hashId, keyCode);
 
2192
    };
 
2193
    this.setOverwrite = function(overwrite) {
 
2194
        this.session.setOverwrite(overwrite);
 
2195
    };
 
2196
    this.getOverwrite = function() {
 
2197
        return this.session.getOverwrite();
 
2198
    };
 
2199
    this.toggleOverwrite = function() {
 
2200
        this.session.toggleOverwrite();
 
2201
    };
 
2202
    this.setScrollSpeed = function(speed) {
 
2203
        this.setOption("scrollSpeed", speed);
 
2204
    };
 
2205
    this.getScrollSpeed = function() {
 
2206
        return this.getOption("scrollSpeed");
 
2207
    };
 
2208
    this.setDragDelay = function(dragDelay) {
 
2209
        this.setOption("dragDelay", dragDelay);
 
2210
    };
 
2211
    this.getDragDelay = function() {
 
2212
        return this.getOption("dragDelay");
 
2213
    };
 
2214
    this.setSelectionStyle = function(val) {
 
2215
        this.setOption("selectionStyle", val);
 
2216
    };
 
2217
    this.getSelectionStyle = function() {
 
2218
        return this.getOption("selectionStyle");
 
2219
    };
 
2220
    this.setHighlightActiveLine = function(shouldHighlight) {
 
2221
        this.setOption("highlightActiveLine", shouldHighlight);
 
2222
    };
 
2223
    this.getHighlightActiveLine = function() {
 
2224
        return this.getOption("highlightActiveLine");
 
2225
    };
 
2226
    this.setHighlightGutterLine = function(shouldHighlight) {
 
2227
        this.setOption("highlightGutterLine", shouldHighlight);
 
2228
    };
 
2229
 
 
2230
    this.getHighlightGutterLine = function() {
 
2231
        return this.getOption("highlightGutterLine");
 
2232
    };
 
2233
    this.setHighlightSelectedWord = function(shouldHighlight) {
 
2234
        this.setOption("highlightSelectedWord", shouldHighlight);
 
2235
    };
 
2236
    this.getHighlightSelectedWord = function() {
 
2237
        return this.$highlightSelectedWord;
 
2238
    };
 
2239
 
 
2240
    this.setAnimatedScroll = function(shouldAnimate){
 
2241
        this.renderer.setAnimatedScroll(shouldAnimate);
 
2242
    };
 
2243
 
 
2244
    this.getAnimatedScroll = function(){
 
2245
        return this.renderer.getAnimatedScroll();
 
2246
    };
 
2247
    this.setShowInvisibles = function(showInvisibles) {
 
2248
        this.renderer.setShowInvisibles(showInvisibles);
 
2249
    };
 
2250
    this.getShowInvisibles = function() {
 
2251
        return this.renderer.getShowInvisibles();
 
2252
    };
 
2253
 
 
2254
    this.setDisplayIndentGuides = function(display) {
 
2255
        this.renderer.setDisplayIndentGuides(display);
 
2256
    };
 
2257
 
 
2258
    this.getDisplayIndentGuides = function() {
 
2259
        return this.renderer.getDisplayIndentGuides();
 
2260
    };
 
2261
    this.setShowPrintMargin = function(showPrintMargin) {
 
2262
        this.renderer.setShowPrintMargin(showPrintMargin);
 
2263
    };
 
2264
    this.getShowPrintMargin = function() {
 
2265
        return this.renderer.getShowPrintMargin();
 
2266
    };
 
2267
    this.setPrintMarginColumn = function(showPrintMargin) {
 
2268
        this.renderer.setPrintMarginColumn(showPrintMargin);
 
2269
    };
 
2270
    this.getPrintMarginColumn = function() {
 
2271
        return this.renderer.getPrintMarginColumn();
 
2272
    };
 
2273
    this.setReadOnly = function(readOnly) {
 
2274
        this.setOption("readOnly", readOnly);
 
2275
    };
 
2276
    this.getReadOnly = function() {
 
2277
        return this.getOption("readOnly");
 
2278
    };
 
2279
    this.setBehavioursEnabled = function (enabled) {
 
2280
        this.setOption("behavioursEnabled", enabled);
 
2281
    };
 
2282
    this.getBehavioursEnabled = function () {
 
2283
        return this.getOption("behavioursEnabled");
 
2284
    };
 
2285
    this.setWrapBehavioursEnabled = function (enabled) {
 
2286
        this.setOption("wrapBehavioursEnabled", enabled);
 
2287
    };
 
2288
    this.getWrapBehavioursEnabled = function () {
 
2289
        return this.getOption("wrapBehavioursEnabled");
 
2290
    };
 
2291
    this.setShowFoldWidgets = function(show) {
 
2292
        this.setOption("showFoldWidgets", show);
 
2293
 
 
2294
    };
 
2295
    this.getShowFoldWidgets = function() {
 
2296
        return this.getOption("showFoldWidgets");
 
2297
    };
 
2298
 
 
2299
    this.setFadeFoldWidgets = function(fade) {
 
2300
        this.setOption("fadeFoldWidgets", fade);
 
2301
    };
 
2302
 
 
2303
    this.getFadeFoldWidgets = function() {
 
2304
        return this.getOption("fadeFoldWidgets");
 
2305
    };
 
2306
    this.remove = function(dir) {
 
2307
        if (this.selection.isEmpty()){
 
2308
            if (dir == "left")
 
2309
                this.selection.selectLeft();
 
2310
            else
 
2311
                this.selection.selectRight();
 
2312
        }
 
2313
 
 
2314
        var range = this.getSelectionRange();
 
2315
        if (this.getBehavioursEnabled()) {
 
2316
            var session = this.session;
 
2317
            var state = session.getState(range.start.row);
 
2318
            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
 
2319
            if (new_range)
 
2320
                range = new_range;
 
2321
        }
 
2322
 
 
2323
        this.session.remove(range);
 
2324
        this.clearSelection();
 
2325
    };
 
2326
    this.removeWordRight = function() {
 
2327
        if (this.selection.isEmpty())
 
2328
            this.selection.selectWordRight();
 
2329
 
 
2330
        this.session.remove(this.getSelectionRange());
 
2331
        this.clearSelection();
 
2332
    };
 
2333
    this.removeWordLeft = function() {
 
2334
        if (this.selection.isEmpty())
 
2335
            this.selection.selectWordLeft();
 
2336
 
 
2337
        this.session.remove(this.getSelectionRange());
 
2338
        this.clearSelection();
 
2339
    };
 
2340
    this.removeToLineStart = function() {
 
2341
        if (this.selection.isEmpty())
 
2342
            this.selection.selectLineStart();
 
2343
 
 
2344
        this.session.remove(this.getSelectionRange());
 
2345
        this.clearSelection();
 
2346
    };
 
2347
    this.removeToLineEnd = function() {
 
2348
        if (this.selection.isEmpty())
 
2349
            this.selection.selectLineEnd();
 
2350
 
 
2351
        var range = this.getSelectionRange();
 
2352
        if (range.start.column == range.end.column && range.start.row == range.end.row) {
 
2353
            range.end.column = 0;
 
2354
            range.end.row++;
 
2355
        }
 
2356
 
 
2357
        this.session.remove(range);
 
2358
        this.clearSelection();
 
2359
    };
 
2360
    this.splitLine = function() {
 
2361
        if (!this.selection.isEmpty()) {
 
2362
            this.session.remove(this.getSelectionRange());
 
2363
            this.clearSelection();
 
2364
        }
 
2365
 
 
2366
        var cursor = this.getCursorPosition();
 
2367
        this.insert("\n");
 
2368
        this.moveCursorToPosition(cursor);
 
2369
    };
 
2370
    this.transposeLetters = function() {
 
2371
        if (!this.selection.isEmpty()) {
 
2372
            return;
 
2373
        }
 
2374
 
 
2375
        var cursor = this.getCursorPosition();
 
2376
        var column = cursor.column;
 
2377
        if (column === 0)
 
2378
            return;
 
2379
 
 
2380
        var line = this.session.getLine(cursor.row);
 
2381
        var swap, range;
 
2382
        if (column < line.length) {
 
2383
            swap = line.charAt(column) + line.charAt(column-1);
 
2384
            range = new Range(cursor.row, column-1, cursor.row, column+1);
 
2385
        }
 
2386
        else {
 
2387
            swap = line.charAt(column-1) + line.charAt(column-2);
 
2388
            range = new Range(cursor.row, column-2, cursor.row, column);
 
2389
        }
 
2390
        this.session.replace(range, swap);
 
2391
    };
 
2392
    this.toLowerCase = function() {
 
2393
        var originalRange = this.getSelectionRange();
 
2394
        if (this.selection.isEmpty()) {
 
2395
            this.selection.selectWord();
 
2396
        }
 
2397
 
 
2398
        var range = this.getSelectionRange();
 
2399
        var text = this.session.getTextRange(range);
 
2400
        this.session.replace(range, text.toLowerCase());
 
2401
        this.selection.setSelectionRange(originalRange);
 
2402
    };
 
2403
    this.toUpperCase = function() {
 
2404
        var originalRange = this.getSelectionRange();
 
2405
        if (this.selection.isEmpty()) {
 
2406
            this.selection.selectWord();
 
2407
        }
 
2408
 
 
2409
        var range = this.getSelectionRange();
 
2410
        var text = this.session.getTextRange(range);
 
2411
        this.session.replace(range, text.toUpperCase());
 
2412
        this.selection.setSelectionRange(originalRange);
 
2413
    };
 
2414
    this.indent = function() {
 
2415
        var session = this.session;
 
2416
        var range = this.getSelectionRange();
 
2417
 
 
2418
        if (range.start.row < range.end.row || range.start.column < range.end.column) {
 
2419
            var rows = this.$getSelectedRows();
 
2420
            session.indentRows(rows.first, rows.last, "\t");
 
2421
        } else {
 
2422
            var indentString;
 
2423
 
 
2424
            if (this.session.getUseSoftTabs()) {
 
2425
                var size        = session.getTabSize(),
 
2426
                    position    = this.getCursorPosition(),
 
2427
                    column      = session.documentToScreenColumn(position.row, position.column),
 
2428
                    count       = (size - column % size);
 
2429
 
 
2430
                indentString = lang.stringRepeat(" ", count);
 
2431
            } else
 
2432
                indentString = "\t";
 
2433
            return this.insert(indentString);
 
2434
        }
 
2435
    };
 
2436
    this.blockIndent = function() {
 
2437
        var rows = this.$getSelectedRows();
 
2438
        this.session.indentRows(rows.first, rows.last, "\t");
 
2439
    };
 
2440
    this.blockOutdent = function() {
 
2441
        var selection = this.session.getSelection();
 
2442
        this.session.outdentRows(selection.getRange());
 
2443
    };
 
2444
    this.sortLines = function() {
 
2445
        var rows = this.$getSelectedRows();
 
2446
        var session = this.session;
 
2447
 
 
2448
        var lines = [];
 
2449
        for (i = rows.first; i <= rows.last; i++)
 
2450
            lines.push(session.getLine(i));
 
2451
 
 
2452
        lines.sort(function(a, b) {
 
2453
            if (a.toLowerCase() < b.toLowerCase()) return -1;
 
2454
            if (a.toLowerCase() > b.toLowerCase()) return 1;
 
2455
            return 0;
 
2456
        });
 
2457
 
 
2458
        var deleteRange = new Range(0, 0, 0, 0);
 
2459
        for (var i = rows.first; i <= rows.last; i++) {
 
2460
            var line = session.getLine(i);
 
2461
            deleteRange.start.row = i;
 
2462
            deleteRange.end.row = i;
 
2463
            deleteRange.end.column = line.length;
 
2464
            session.replace(deleteRange, lines[i-rows.first]);
 
2465
        }
 
2466
    };
 
2467
    this.toggleCommentLines = function() {
 
2468
        var state = this.session.getState(this.getCursorPosition().row);
 
2469
        var rows = this.$getSelectedRows();
 
2470
        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
 
2471
    };
 
2472
    this.getNumberAt = function( row, column ) {
 
2473
        var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g
 
2474
        _numberRx.lastIndex = 0
 
2475
 
 
2476
        var s = this.session.getLine(row)
 
2477
        while(_numberRx.lastIndex < column - 1 ){
 
2478
            var m = _numberRx.exec(s)
 
2479
            if(m.index <= column && m.index+m[0].length >= column){
 
2480
                var number = {
 
2481
                    value: m[0],
 
2482
                    start: m.index,
 
2483
                    end: m.index+m[0].length
 
2484
 
 
2485
                }
 
2486
                return number
 
2487
            }
 
2488
        }
 
2489
        return null;
 
2490
    };
 
2491
    this.modifyNumber = function(amount) {
 
2492
        var row = this.selection.getCursor().row;
 
2493
        var column = this.selection.getCursor().column;
 
2494
        var charRange = new Range(row, column-1, row, column);
 
2495
 
 
2496
        var c = this.session.getTextRange(charRange);
 
2497
        if (!isNaN(parseFloat(c)) && isFinite(c)) {
 
2498
            var nr = this.getNumberAt(row, column);
 
2499
            if (nr) {
 
2500
                var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
 
2501
                var decimals = nr.start + nr.value.length - fp;
 
2502
 
 
2503
                var t = parseFloat(nr.value);
 
2504
                t *= Math.pow(10, decimals);
 
2505
 
 
2506
 
 
2507
                if(fp !== nr.end && column < fp){
 
2508
                    amount *= Math.pow(10, nr.end - column - 1);
 
2509
                } else {
 
2510
                    amount *= Math.pow(10, nr.end - column);
 
2511
                }
 
2512
 
 
2513
                t += amount;
 
2514
                t /= Math.pow(10, decimals);
 
2515
                var nnr = t.toFixed(decimals);
 
2516
                var replaceRange = new Range(row, nr.start, row, nr.end);
 
2517
                this.session.replace(replaceRange, nnr);
 
2518
                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
 
2519
 
 
2520
            }
 
2521
        }
 
2522
    };
 
2523
    this.removeLines = function() {
 
2524
        var rows = this.$getSelectedRows();
 
2525
        var range;
 
2526
        if (rows.first === 0 || rows.last+1 < this.session.getLength())
 
2527
            range = new Range(rows.first, 0, rows.last+1, 0);
 
2528
        else
 
2529
            range = new Range(
 
2530
                rows.first-1, this.session.getLine(rows.first-1).length,
 
2531
                rows.last, this.session.getLine(rows.last).length
 
2532
            );
 
2533
        this.session.remove(range);
 
2534
        this.clearSelection();
 
2535
    };
 
2536
 
 
2537
    this.duplicateSelection = function() {
 
2538
        var sel = this.selection;
 
2539
        var doc = this.session;
 
2540
        var range = sel.getRange();
 
2541
        if (range.isEmpty()) {
 
2542
            var row = range.start.row;
 
2543
            doc.duplicateLines(row, row);
 
2544
        } else {
 
2545
            var point = reverse ? range.start : range.end;
 
2546
            var endPoint = doc.insert(point, doc.getTextRange(range), false);
 
2547
            range.start = point;
 
2548
            range.end = endPoint;
 
2549
 
 
2550
            sel.setSelectionRange(range, reverse)
 
2551
        }
 
2552
    };
 
2553
    this.moveLinesDown = function() {
 
2554
        this.$moveLines(function(firstRow, lastRow) {
 
2555
            return this.session.moveLinesDown(firstRow, lastRow);
 
2556
        });
 
2557
    };
 
2558
    this.moveLinesUp = function() {
 
2559
        this.$moveLines(function(firstRow, lastRow) {
 
2560
            return this.session.moveLinesUp(firstRow, lastRow);
 
2561
        });
 
2562
    };
 
2563
    this.moveText = function(range, toPosition) {
 
2564
        return this.session.moveText(range, toPosition);
 
2565
    };
 
2566
    this.copyLinesUp = function() {
 
2567
        this.$moveLines(function(firstRow, lastRow) {
 
2568
            this.session.duplicateLines(firstRow, lastRow);
 
2569
            return 0;
 
2570
        });
 
2571
    };
 
2572
    this.copyLinesDown = function() {
 
2573
        this.$moveLines(function(firstRow, lastRow) {
 
2574
            return this.session.duplicateLines(firstRow, lastRow);
 
2575
        });
 
2576
    };
 
2577
    this.$moveLines = function(mover) {
 
2578
        var selection = this.selection;
 
2579
        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
 
2580
            var range = selection.toOrientedRange();
 
2581
            var rows = this.$getSelectedRows(range);
 
2582
            var linesMoved = mover.call(this, rows.first, rows.last);
 
2583
            range.moveBy(linesMoved, 0);
 
2584
            selection.fromOrientedRange(range);
 
2585
        } else {
 
2586
            var ranges = selection.rangeList.ranges;
 
2587
            selection.rangeList.detach(this.session);
 
2588
            
 
2589
            for (var i = ranges.length; i--; ) {
 
2590
                var rangeIndex = i;
 
2591
                var rows = ranges[i].collapseRows();
 
2592
                var last = rows.end.row;
 
2593
                var first = rows.start.row;
 
2594
                while (i--) {
 
2595
                    var rows = ranges[i].collapseRows();
 
2596
                    if (first - rows.end.row <= 1)
 
2597
                        first = rows.end.row;
 
2598
                    else
 
2599
                        break;
 
2600
                }
 
2601
                i++;
 
2602
                
 
2603
                var linesMoved = mover.call(this, first, last);
 
2604
                while (rangeIndex >= i) {
 
2605
                    ranges[rangeIndex].moveBy(linesMoved, 0);
 
2606
                    rangeIndex--;
 
2607
                }
 
2608
            }
 
2609
            selection.fromOrientedRange(selection.ranges[0]);
 
2610
            selection.rangeList.attach(this.session);
 
2611
        }
 
2612
    };
 
2613
    this.$getSelectedRows = function() {
 
2614
        var range = this.getSelectionRange().collapseRows();
 
2615
 
 
2616
        return {
 
2617
            first: range.start.row,
 
2618
            last: range.end.row
 
2619
        };
 
2620
    };
 
2621
 
 
2622
    this.onCompositionStart = function(text) {
 
2623
        this.renderer.showComposition(this.getCursorPosition());
 
2624
    };
 
2625
 
 
2626
    this.onCompositionUpdate = function(text) {
 
2627
        this.renderer.setCompositionText(text);
 
2628
    };
 
2629
 
 
2630
    this.onCompositionEnd = function() {
 
2631
        this.renderer.hideComposition();
 
2632
    };
 
2633
    this.getFirstVisibleRow = function() {
 
2634
        return this.renderer.getFirstVisibleRow();
 
2635
    };
 
2636
    this.getLastVisibleRow = function() {
 
2637
        return this.renderer.getLastVisibleRow();
 
2638
    };
 
2639
    this.isRowVisible = function(row) {
 
2640
        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
 
2641
    };
 
2642
    this.isRowFullyVisible = function(row) {
 
2643
        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
 
2644
    };
 
2645
    this.$getVisibleRowCount = function() {
 
2646
        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
 
2647
    };
 
2648
 
 
2649
    this.$moveByPage = function(dir, select) {
 
2650
        var renderer = this.renderer;
 
2651
        var config = this.renderer.layerConfig;
 
2652
        var rows = dir * Math.floor(config.height / config.lineHeight);
 
2653
 
 
2654
        this.$blockScrolling++;
 
2655
        if (select == true) {
 
2656
            this.selection.$moveSelection(function(){
 
2657
                this.moveCursorBy(rows, 0);
 
2658
            });
 
2659
        } else if (select == false) {
 
2660
            this.selection.moveCursorBy(rows, 0);
 
2661
            this.selection.clearSelection();
 
2662
        }
 
2663
        this.$blockScrolling--;
 
2664
 
 
2665
        var scrollTop = renderer.scrollTop;
 
2666
 
 
2667
        renderer.scrollBy(0, rows * config.lineHeight);
 
2668
        if (select != null)
 
2669
            renderer.scrollCursorIntoView(null, 0.5);
 
2670
 
 
2671
        renderer.animateScrolling(scrollTop);
 
2672
    };
 
2673
    this.selectPageDown = function() {
 
2674
        this.$moveByPage(1, true);
 
2675
    };
 
2676
    this.selectPageUp = function() {
 
2677
        this.$moveByPage(-1, true);
 
2678
    };
 
2679
    this.gotoPageDown = function() {
 
2680
       this.$moveByPage(1, false);
 
2681
    };
 
2682
    this.gotoPageUp = function() {
 
2683
        this.$moveByPage(-1, false);
 
2684
    };
 
2685
    this.scrollPageDown = function() {
 
2686
        this.$moveByPage(1);
 
2687
    };
 
2688
    this.scrollPageUp = function() {
 
2689
        this.$moveByPage(-1);
 
2690
    };
 
2691
    this.scrollToRow = function(row) {
 
2692
        this.renderer.scrollToRow(row);
 
2693
    };
 
2694
    this.scrollToLine = function(line, center, animate, callback) {
 
2695
        this.renderer.scrollToLine(line, center, animate, callback);
 
2696
    };
 
2697
    this.centerSelection = function() {
 
2698
        var range = this.getSelectionRange();
 
2699
        var pos = {
 
2700
            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
 
2701
            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
 
2702
        }
 
2703
        this.renderer.alignCursor(pos, 0.5);
 
2704
    };
 
2705
    this.getCursorPosition = function() {
 
2706
        return this.selection.getCursor();
 
2707
    };
 
2708
    this.getCursorPositionScreen = function() {
 
2709
        return this.session.documentToScreenPosition(this.getCursorPosition());
 
2710
    };
 
2711
    this.getSelectionRange = function() {
 
2712
        return this.selection.getRange();
 
2713
    };
 
2714
    this.selectAll = function() {
 
2715
        this.$blockScrolling += 1;
 
2716
        this.selection.selectAll();
 
2717
        this.$blockScrolling -= 1;
 
2718
    };
 
2719
    this.clearSelection = function() {
 
2720
        this.selection.clearSelection();
 
2721
    };
 
2722
    this.moveCursorTo = function(row, column) {
 
2723
        this.selection.moveCursorTo(row, column);
 
2724
    };
 
2725
    this.moveCursorToPosition = function(pos) {
 
2726
        this.selection.moveCursorToPosition(pos);
 
2727
    };
 
2728
    this.jumpToMatching = function(select) {
 
2729
        var cursor = this.getCursorPosition();
 
2730
 
 
2731
        var range = this.session.getBracketRange(cursor);
 
2732
        if (!range) {
 
2733
            range = this.find({
 
2734
                needle: /[{}()\[\]]/g,
 
2735
                preventScroll:true,
 
2736
                start: {row: cursor.row, column: cursor.column - 1}
 
2737
            });
 
2738
            if (!range)
 
2739
                return;
 
2740
            var pos = range.start;
 
2741
            if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
 
2742
                range = this.session.getBracketRange(pos);
 
2743
        }
 
2744
 
 
2745
        pos = range && range.cursor || pos;
 
2746
        if (pos) {
 
2747
            if (select) {
 
2748
                if (range && range.isEqual(this.getSelectionRange()))
 
2749
                    this.clearSelection();
 
2750
                else
 
2751
                    this.selection.selectTo(pos.row, pos.column);
 
2752
            } else {
 
2753
                this.clearSelection();
 
2754
                this.moveCursorTo(pos.row, pos.column);
 
2755
            }
 
2756
        }
 
2757
    };
 
2758
    this.gotoLine = function(lineNumber, column, animate) {
 
2759
        this.selection.clearSelection();
 
2760
        this.session.unfold({row: lineNumber - 1, column: column || 0});
 
2761
 
 
2762
        this.$blockScrolling += 1;
 
2763
        this.moveCursorTo(lineNumber - 1, column || 0);
 
2764
        this.$blockScrolling -= 1;
 
2765
 
 
2766
        if (!this.isRowFullyVisible(lineNumber - 1))
 
2767
            this.scrollToLine(lineNumber - 1, true, animate);
 
2768
    };
 
2769
    this.navigateTo = function(row, column) {
 
2770
        this.clearSelection();
 
2771
        this.moveCursorTo(row, column);
 
2772
    };
 
2773
    this.navigateUp = function(times) {
 
2774
        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
 
2775
            var selectionStart = this.selection.anchor.getPosition();
 
2776
            return this.moveCursorToPosition(selectionStart);
 
2777
        }
 
2778
        this.selection.clearSelection();
 
2779
        times = times || 1;
 
2780
        this.selection.moveCursorBy(-times, 0);
 
2781
    };
 
2782
    this.navigateDown = function(times) {
 
2783
        if (this.selection.isMultiLine() && this.selection.isBackwards()) {
 
2784
            var selectionEnd = this.selection.anchor.getPosition();
 
2785
            return this.moveCursorToPosition(selectionEnd);
 
2786
        }
 
2787
        this.selection.clearSelection();
 
2788
        times = times || 1;
 
2789
        this.selection.moveCursorBy(times, 0);
 
2790
    };
 
2791
    this.navigateLeft = function(times) {
 
2792
        if (!this.selection.isEmpty()) {
 
2793
            var selectionStart = this.getSelectionRange().start;
 
2794
            this.moveCursorToPosition(selectionStart);
 
2795
        }
 
2796
        else {
 
2797
            times = times || 1;
 
2798
            while (times--) {
 
2799
                this.selection.moveCursorLeft();
 
2800
            }
 
2801
        }
 
2802
        this.clearSelection();
 
2803
    };
 
2804
    this.navigateRight = function(times) {
 
2805
        if (!this.selection.isEmpty()) {
 
2806
            var selectionEnd = this.getSelectionRange().end;
 
2807
            this.moveCursorToPosition(selectionEnd);
 
2808
        }
 
2809
        else {
 
2810
            times = times || 1;
 
2811
            while (times--) {
 
2812
                this.selection.moveCursorRight();
 
2813
            }
 
2814
        }
 
2815
        this.clearSelection();
 
2816
    };
 
2817
    this.navigateLineStart = function() {
 
2818
        this.selection.moveCursorLineStart();
 
2819
        this.clearSelection();
 
2820
    };
 
2821
    this.navigateLineEnd = function() {
 
2822
        this.selection.moveCursorLineEnd();
 
2823
        this.clearSelection();
 
2824
    };
 
2825
    this.navigateFileEnd = function() {
 
2826
        var scrollTop = this.renderer.scrollTop;
 
2827
        this.selection.moveCursorFileEnd();
 
2828
        this.clearSelection();
 
2829
        this.renderer.animateScrolling(scrollTop);
 
2830
    };
 
2831
    this.navigateFileStart = function() {
 
2832
        var scrollTop = this.renderer.scrollTop;
 
2833
        this.selection.moveCursorFileStart();
 
2834
        this.clearSelection();
 
2835
        this.renderer.animateScrolling(scrollTop);
 
2836
    };
 
2837
    this.navigateWordRight = function() {
 
2838
        this.selection.moveCursorWordRight();
 
2839
        this.clearSelection();
 
2840
    };
 
2841
    this.navigateWordLeft = function() {
 
2842
        this.selection.moveCursorWordLeft();
 
2843
        this.clearSelection();
 
2844
    };
 
2845
    this.replace = function(replacement, options) {
 
2846
        if (options)
 
2847
            this.$search.set(options);
 
2848
 
 
2849
        var range = this.$search.find(this.session);
 
2850
        var replaced = 0;
 
2851
        if (!range)
 
2852
            return replaced;
 
2853
 
 
2854
        if (this.$tryReplace(range, replacement)) {
 
2855
            replaced = 1;
 
2856
        }
 
2857
        if (range !== null) {
 
2858
            this.selection.setSelectionRange(range);
 
2859
            this.renderer.scrollSelectionIntoView(range.start, range.end);
 
2860
        }
 
2861
 
 
2862
        return replaced;
 
2863
    };
 
2864
    this.replaceAll = function(replacement, options) {
 
2865
        if (options) {
 
2866
            this.$search.set(options);
 
2867
        }
 
2868
 
 
2869
        var ranges = this.$search.findAll(this.session);
 
2870
        var replaced = 0;
 
2871
        if (!ranges.length)
 
2872
            return replaced;
 
2873
 
 
2874
        this.$blockScrolling += 1;
 
2875
 
 
2876
        var selection = this.getSelectionRange();
 
2877
        this.clearSelection();
 
2878
        this.selection.moveCursorTo(0, 0);
 
2879
 
 
2880
        for (var i = ranges.length - 1; i >= 0; --i) {
 
2881
            if(this.$tryReplace(ranges[i], replacement)) {
 
2882
                replaced++;
 
2883
            }
 
2884
        }
 
2885
 
 
2886
        this.selection.setSelectionRange(selection);
 
2887
        this.$blockScrolling -= 1;
 
2888
 
 
2889
        return replaced;
 
2890
    };
 
2891
 
 
2892
    this.$tryReplace = function(range, replacement) {
 
2893
        var input = this.session.getTextRange(range);
 
2894
        replacement = this.$search.replace(input, replacement);
 
2895
        if (replacement !== null) {
 
2896
            range.end = this.session.replace(range, replacement);
 
2897
            return range;
 
2898
        } else {
 
2899
            return null;
 
2900
        }
 
2901
    };
 
2902
    this.getLastSearchOptions = function() {
 
2903
        return this.$search.getOptions();
 
2904
    };
 
2905
    this.find = function(needle, options, animate) {
 
2906
        if (!options)
 
2907
            options = {};
 
2908
 
 
2909
        if (typeof needle == "string" || needle instanceof RegExp)
 
2910
            options.needle = needle;
 
2911
        else if (typeof needle == "object")
 
2912
            oop.mixin(options, needle);
 
2913
 
 
2914
        var range = this.selection.getRange();
 
2915
        if (options.needle == null) {
 
2916
            needle = this.session.getTextRange(range)
 
2917
                || this.$search.$options.needle;
 
2918
            if (!needle) {
 
2919
                range = this.session.getWordRange(range.start.row, range.start.column);
 
2920
                needle = this.session.getTextRange(range);
 
2921
            }
 
2922
            this.$search.set({needle: needle});
 
2923
        }
 
2924
 
 
2925
        this.$search.set(options);
 
2926
        if (!options.start)
 
2927
            this.$search.set({start: range});
 
2928
 
 
2929
        var newRange = this.$search.find(this.session);
 
2930
        if (options.preventScroll)
 
2931
            return newRange;
 
2932
        if (newRange) {
 
2933
            this.revealRange(newRange, animate);
 
2934
            return newRange;
 
2935
        }
 
2936
        if (options.backwards)
 
2937
            range.start = range.end;
 
2938
        else
 
2939
            range.end = range.start;
 
2940
        this.selection.setRange(range);
 
2941
    };
 
2942
    this.findNext = function(options, animate) {
 
2943
        this.find({skipCurrent: true, backwards: false}, options, animate);
 
2944
    };
 
2945
    this.findPrevious = function(options, animate) {
 
2946
        this.find(options, {skipCurrent: true, backwards: true}, animate);
 
2947
    };
 
2948
 
 
2949
    this.revealRange = function(range, animate) {
 
2950
        this.$blockScrolling += 1;
 
2951
        this.session.unfold(range);
 
2952
        this.selection.setSelectionRange(range);
 
2953
        this.$blockScrolling -= 1;
 
2954
 
 
2955
        var scrollTop = this.renderer.scrollTop;
 
2956
        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
 
2957
        if (animate != false)
 
2958
            this.renderer.animateScrolling(scrollTop);
 
2959
    };
 
2960
    this.undo = function() {
 
2961
        this.$blockScrolling++;
 
2962
        this.session.getUndoManager().undo();
 
2963
        this.$blockScrolling--;
 
2964
        this.renderer.scrollCursorIntoView(null, 0.5);
 
2965
    };
 
2966
    this.redo = function() {
 
2967
        this.$blockScrolling++;
 
2968
        this.session.getUndoManager().redo();
 
2969
        this.$blockScrolling--;
 
2970
        this.renderer.scrollCursorIntoView(null, 0.5);
 
2971
    };
 
2972
    this.destroy = function() {
 
2973
        this.renderer.destroy();
 
2974
        this._emit("destroy", this);
 
2975
    };
 
2976
    this.setAutoScrollEditorIntoView = function(enable) {
 
2977
        if (enable === true)
 
2978
            return;
 
2979
        var rect;
 
2980
        var self = this;
 
2981
        var shouldScroll = false;
 
2982
        if (!this.$scrollAnchor)
 
2983
            this.$scrollAnchor = document.createElement("div");
 
2984
        var scrollAnchor = this.$scrollAnchor;
 
2985
        scrollAnchor.style.cssText = "position:absolute";
 
2986
        this.container.insertBefore(scrollAnchor, this.container.firstChild);
 
2987
        var onChangeSelection = this.on("changeSelection", function() {
 
2988
            shouldScroll = true;
 
2989
        });
 
2990
        var onBeforeRender = this.renderer.on("beforeRender", function() {
 
2991
            if (shouldScroll)
 
2992
                rect = self.renderer.container.getBoundingClientRect();
 
2993
        });
 
2994
        var onAfterRender = this.renderer.on("afterRender", function() {
 
2995
            if (shouldScroll && rect && self.isFocused()) {
 
2996
                var renderer = self.renderer;
 
2997
                var pos = renderer.$cursorLayer.$pixelPos;
 
2998
                var config = renderer.layerConfig;
 
2999
                var top = pos.top - config.offset;
 
3000
                if (pos.top >= 0 && top + rect.top < 0) {
 
3001
                    shouldScroll = true;
 
3002
                } else if (pos.top < config.height &&
 
3003
                    pos.top + rect.top + config.lineHeight > window.innerHeight) {
 
3004
                    shouldScroll = false;
 
3005
                } else {
 
3006
                    shouldScroll = null;
 
3007
                }
 
3008
                if (shouldScroll != null) {
 
3009
                    scrollAnchor.style.top = top + "px";
 
3010
                    scrollAnchor.style.left = pos.left + "px";
 
3011
                    scrollAnchor.style.height = config.lineHeight + "px";
 
3012
                    scrollAnchor.scrollIntoView(shouldScroll);
 
3013
                }
 
3014
                shouldScroll = rect = null;
 
3015
            }
 
3016
        });
 
3017
        this.setAutoScrollEditorIntoView = function(enable) {
 
3018
            if (enable === false)
 
3019
                return;
 
3020
            delete this.setAutoScrollEditorIntoView;
 
3021
            this.removeEventListener("changeSelection", onChangeSelection);
 
3022
            this.renderer.removeEventListener("afterRender", onAfterRender);
 
3023
            this.renderer.removeEventListener("beforeRender", onBeforeRender);
 
3024
        };
 
3025
    };
 
3026
 
 
3027
}).call(Editor.prototype);
 
3028
 
 
3029
 
 
3030
 
 
3031
config.defineOptions(Editor.prototype, "editor", {
 
3032
    selectionStyle: {
 
3033
        set: function(style) {
 
3034
            this.onSelectionChange();
 
3035
            this._emit("changeSelectionStyle", {data: style});
 
3036
        },
 
3037
        initialValue: "line",
 
3038
    },
 
3039
    highlightActiveLine: {
 
3040
        set: function() {this.$updateHighlightActiveLine();},
 
3041
        initialValue: true
 
3042
    },
 
3043
    highlightSelectedWord: {
 
3044
        set: function(shouldHighlight) {this.$onSelectionChange();},
 
3045
        initialValue: true
 
3046
    },
 
3047
    readOnly: {
 
3048
        set: function(readOnly) {
 
3049
            this.textInput.setReadOnly(readOnly);
 
3050
            this.renderer.$cursorLayer.setBlinking(!readOnly);
 
3051
        },
 
3052
        initialValue: false
 
3053
    },
 
3054
    behavioursEnabled: {initialValue: true},
 
3055
    wrapBehavioursEnabled: {initialValue: true},
 
3056
 
 
3057
    highlightGutterLine: "renderer",
 
3058
    animatedScroll: "renderer",
 
3059
    showInvisibles: "renderer",
 
3060
    showPrintMargin: "renderer",
 
3061
    printMarginColumn: "renderer",
 
3062
    fadeFoldWidgets: "renderer",
 
3063
    showFoldWidgets: "renderer",
 
3064
    showGutter: "renderer",
 
3065
    displayIndentGuides: "renderer",
 
3066
 
 
3067
    scrollSpeed: "$mouseHandler",
 
3068
    dragDelay: "$mouseHandler",
 
3069
    focusTimout: "$mouseHandler",
 
3070
 
 
3071
    firstLineNumber: "session",
 
3072
    useWorker: "session",
 
3073
    useSoftTabs: "session",
 
3074
    tabSize: "session",
 
3075
    wrap: "session"
 
3076
});
 
3077
 
 
3078
exports.Editor = Editor;
 
3079
});
 
3080
 
 
3081
define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
 
3082
 
 
3083
 
 
3084
exports.stringReverse = function(string) {
 
3085
    return string.split("").reverse().join("");
 
3086
};
 
3087
 
 
3088
exports.stringRepeat = function (string, count) {
 
3089
    var result = '';
 
3090
    while (count > 0) {
 
3091
        if (count & 1)
 
3092
            result += string;
 
3093
 
 
3094
        if (count >>= 1)
 
3095
            string += string;
 
3096
    }
 
3097
    return result;
 
3098
};
 
3099
 
 
3100
var trimBeginRegexp = /^\s\s*/;
 
3101
var trimEndRegexp = /\s\s*$/;
 
3102
 
 
3103
exports.stringTrimLeft = function (string) {
 
3104
    return string.replace(trimBeginRegexp, '');
 
3105
};
 
3106
 
 
3107
exports.stringTrimRight = function (string) {
 
3108
    return string.replace(trimEndRegexp, '');
 
3109
};
 
3110
 
 
3111
exports.copyObject = function(obj) {
 
3112
    var copy = {};
 
3113
    for (var key in obj) {
 
3114
        copy[key] = obj[key];
 
3115
    }
 
3116
    return copy;
 
3117
};
 
3118
 
 
3119
exports.copyArray = function(array){
 
3120
    var copy = [];
 
3121
    for (var i=0, l=array.length; i<l; i++) {
 
3122
        if (array[i] && typeof array[i] == "object")
 
3123
            copy[i] = this.copyObject( array[i] );
 
3124
        else 
 
3125
            copy[i] = array[i];
 
3126
    }
 
3127
    return copy;
 
3128
};
 
3129
 
 
3130
exports.deepCopy = function (obj) {
 
3131
    if (typeof obj != "object") {
 
3132
        return obj;
 
3133
    }
 
3134
    
 
3135
    var copy = obj.constructor();
 
3136
    for (var key in obj) {
 
3137
        if (typeof obj[key] == "object") {
 
3138
            copy[key] = this.deepCopy(obj[key]);
 
3139
        } else {
 
3140
            copy[key] = obj[key];
 
3141
        }
 
3142
    }
 
3143
    return copy;
 
3144
};
 
3145
 
 
3146
exports.arrayToMap = function(arr) {
 
3147
    var map = {};
 
3148
    for (var i=0; i<arr.length; i++) {
 
3149
        map[arr[i]] = 1;
 
3150
    }
 
3151
    return map;
 
3152
 
 
3153
};
 
3154
 
 
3155
exports.createMap = function(props) {
 
3156
    var map = Object.create(null);
 
3157
    for (var i in props) {
 
3158
        map[i] = props[i];
 
3159
    }
 
3160
    return map;
 
3161
};
 
3162
exports.arrayRemove = function(array, value) {
 
3163
  for (var i = 0; i <= array.length; i++) {
 
3164
    if (value === array[i]) {
 
3165
      array.splice(i, 1);
 
3166
    }
 
3167
  }
 
3168
};
 
3169
 
 
3170
exports.escapeRegExp = function(str) {
 
3171
    return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
 
3172
};
 
3173
 
 
3174
exports.escapeHTML = function(str) {
 
3175
    return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
 
3176
};
 
3177
 
 
3178
exports.getMatchOffsets = function(string, regExp) {
 
3179
    var matches = [];
 
3180
 
 
3181
    string.replace(regExp, function(str) {
 
3182
        matches.push({
 
3183
            offset: arguments[arguments.length-2],
 
3184
            length: str.length
 
3185
        });
 
3186
    });
 
3187
 
 
3188
    return matches;
 
3189
};
 
3190
exports.deferredCall = function(fcn) {
 
3191
 
 
3192
    var timer = null;
 
3193
    var callback = function() {
 
3194
        timer = null;
 
3195
        fcn();
 
3196
    };
 
3197
 
 
3198
    var deferred = function(timeout) {
 
3199
        deferred.cancel();
 
3200
        timer = setTimeout(callback, timeout || 0);
 
3201
        return deferred;
 
3202
    };
 
3203
 
 
3204
    deferred.schedule = deferred;
 
3205
 
 
3206
    deferred.call = function() {
 
3207
        this.cancel();
 
3208
        fcn();
 
3209
        return deferred;
 
3210
    };
 
3211
 
 
3212
    deferred.cancel = function() {
 
3213
        clearTimeout(timer);
 
3214
        timer = null;
 
3215
        return deferred;
 
3216
    };
 
3217
 
 
3218
    return deferred;
 
3219
};
 
3220
 
 
3221
 
 
3222
exports.delayedCall = function(fcn, defaultTimeout) {
 
3223
    var timer = null;
 
3224
    var callback = function() {
 
3225
        timer = null;
 
3226
        fcn();
 
3227
    };
 
3228
 
 
3229
    var _self = function(timeout) {
 
3230
        timer && clearTimeout(timer);
 
3231
        timer = setTimeout(callback, timeout || defaultTimeout);
 
3232
    };
 
3233
 
 
3234
    _self.delay = _self;
 
3235
    _self.schedule = function(timeout) {
 
3236
        if (timer == null)
 
3237
            timer = setTimeout(callback, timeout || 0);
 
3238
    };
 
3239
 
 
3240
    _self.call = function() {
 
3241
        this.cancel();
 
3242
        fcn();
 
3243
    };
 
3244
 
 
3245
    _self.cancel = function() {
 
3246
        timer && clearTimeout(timer);
 
3247
        timer = null;
 
3248
    };
 
3249
 
 
3250
    _self.isPending = function() {
 
3251
        return timer;
 
3252
    };
 
3253
 
 
3254
    return _self;
 
3255
};
 
3256
});
 
3257
 
 
3258
define('ace/keyboard/textinput', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/lib/dom', 'ace/lib/lang'], function(require, exports, module) {
 
3259
 
 
3260
 
 
3261
var event = require("../lib/event");
 
3262
var useragent = require("../lib/useragent");
 
3263
var dom = require("../lib/dom");
 
3264
var lang = require("../lib/lang");
 
3265
var BROKEN_SETDATA = useragent.isChrome < 18;
 
3266
 
 
3267
var TextInput = function(parentNode, host) {
 
3268
    var text = dom.createElement("textarea");
 
3269
    text.className = "ace_text-input";
 
3270
    if (useragent.isTouchPad)
 
3271
        text.setAttribute("x-palm-disable-auto-cap", true);
 
3272
 
 
3273
    text.wrap = "off";
 
3274
    text.autocorrect = "off";
 
3275
    text.autocapitalize = "off";
 
3276
    text.spellcheck = false;
 
3277
 
 
3278
    text.style.bottom = "2000em";
 
3279
    parentNode.insertBefore(text, parentNode.firstChild);
 
3280
 
 
3281
    var PLACEHOLDER = "\x01\x01";
 
3282
 
 
3283
    var cut = false;
 
3284
    var copied = false;
 
3285
    var pasted = false;
 
3286
    var inCompostion = false;
 
3287
    var tempStyle = '';
 
3288
    var isSelectionEmpty = true;
 
3289
    try { var isFocused = document.activeElement === text; } catch(e) {}
 
3290
    
 
3291
    event.addListener(text, "blur", function() {
 
3292
        host.onBlur();
 
3293
        isFocused = false;
 
3294
    });
 
3295
    event.addListener(text, "focus", function() {
 
3296
        isFocused = true;
 
3297
        host.onFocus();
 
3298
        resetSelection();
 
3299
    });
 
3300
    this.focus = function() { text.focus(); };
 
3301
    this.blur = function() { text.blur(); };
 
3302
    this.isFocused = function() {
 
3303
        return isFocused;
 
3304
    };
 
3305
    var syncSelection = lang.delayedCall(function() {
 
3306
        isFocused && resetSelection(isSelectionEmpty);
 
3307
    });
 
3308
    var syncValue = lang.delayedCall(function() {
 
3309
         if (!inCompostion) {
 
3310
            text.value = PLACEHOLDER;
 
3311
            isFocused && resetSelection();
 
3312
         }
 
3313
    });
 
3314
 
 
3315
    function resetSelection(isEmpty) {
 
3316
        if (inCompostion)
 
3317
            return;
 
3318
        if (inputHandler) {
 
3319
            selectionStart = 0;
 
3320
            selectionEnd = isEmpty ? 0 : text.value.length - 1;
 
3321
        } else {
 
3322
            var selectionStart = isEmpty ? 2 : 1;
 
3323
            var selectionEnd = 2;
 
3324
        }
 
3325
        try {
 
3326
            text.setSelectionRange(selectionStart, selectionEnd);
 
3327
        } catch(e){}
 
3328
    }
 
3329
 
 
3330
    function resetValue() {
 
3331
        if (inCompostion)
 
3332
            return;
 
3333
        text.value = PLACEHOLDER;
 
3334
        if (useragent.isWebKit)
 
3335
            syncValue.schedule();
 
3336
    }
 
3337
 
 
3338
    useragent.isWebKit || host.addEventListener('changeSelection', function() {
 
3339
        if (host.selection.isEmpty() != isSelectionEmpty) {
 
3340
            isSelectionEmpty = !isSelectionEmpty;
 
3341
            syncSelection.schedule();
 
3342
        }
 
3343
    });
 
3344
 
 
3345
    resetValue();
 
3346
    if (isFocused)
 
3347
        host.onFocus();
 
3348
 
 
3349
 
 
3350
    var isAllSelected = function(text) {
 
3351
        return text.selectionStart === 0 && text.selectionEnd === text.value.length;
 
3352
    };
 
3353
    if (!text.setSelectionRange && text.createTextRange) {
 
3354
        text.setSelectionRange = function(selectionStart, selectionEnd) {
 
3355
            var range = this.createTextRange();
 
3356
            range.collapse(true);
 
3357
            range.moveStart('character', selectionStart);
 
3358
            range.moveEnd('character', selectionEnd);
 
3359
            range.select();
 
3360
        };
 
3361
        isAllSelected = function(text) {
 
3362
            try {
 
3363
                var range = text.ownerDocument.selection.createRange();
 
3364
            }catch(e) {}
 
3365
            if (!range || range.parentElement() != text) return false;
 
3366
                return range.text == text.value;
 
3367
        }
 
3368
    }
 
3369
    if (useragent.isOldIE) {
 
3370
        var inPropertyChange = false;
 
3371
        var onPropertyChange = function(e){
 
3372
            if (inPropertyChange)
 
3373
                return;
 
3374
            var data = text.value;
 
3375
            if (inCompostion || !data || data == PLACEHOLDER)
 
3376
                return;
 
3377
            if (e && data == PLACEHOLDER[0])
 
3378
                return syncProperty.schedule();
 
3379
 
 
3380
            sendText(data);
 
3381
            inPropertyChange = true;
 
3382
            resetValue();
 
3383
            inPropertyChange = false;
 
3384
        };
 
3385
        var syncProperty = lang.delayedCall(onPropertyChange);
 
3386
        event.addListener(text, "propertychange", onPropertyChange);
 
3387
 
 
3388
        var keytable = { 13:1, 27:1 };
 
3389
        event.addListener(text, "keyup", function (e) {
 
3390
            if (inCompostion && (!text.value || keytable[e.keyCode]))
 
3391
                setTimeout(onCompositionEnd, 0);
 
3392
            if ((text.value.charCodeAt(0)||0) < 129) {
 
3393
                return;
 
3394
            }
 
3395
            inCompostion ? onCompositionUpdate() : onCompositionStart();
 
3396
        });
 
3397
    }
 
3398
 
 
3399
    var onSelect = function(e) {
 
3400
        if (cut) {
 
3401
            cut = false;
 
3402
        } else if (copied) {
 
3403
            copied = false;
 
3404
        } else if (isAllSelected(text)) {
 
3405
            host.selectAll();
 
3406
            resetSelection();
 
3407
        } else if (inputHandler) {
 
3408
            resetSelection(host.selection.isEmpty());
 
3409
        }
 
3410
    };
 
3411
 
 
3412
    var inputHandler = null;
 
3413
    this.setInputHandler = function(cb) {inputHandler = cb};
 
3414
    this.getInputHandler = function() {return inputHandler};
 
3415
    
 
3416
    var sendText = function(data) {
 
3417
        if (inputHandler) {
 
3418
            data = inputHandler(data);
 
3419
            inputHandler = null;
 
3420
        }
 
3421
        if (pasted) {
 
3422
            resetSelection();
 
3423
            if (data)
 
3424
                host.onPaste(data);
 
3425
            pasted = false;
 
3426
        } else if (data == PLACEHOLDER[0]) {
 
3427
            if (Date.now() - lastCompositionTime > 100)
 
3428
                host.execCommand("del", {source: "ace"});
 
3429
        } else {
 
3430
            if (data.substring(0, 2) == PLACEHOLDER)
 
3431
                data = data.substr(2);
 
3432
            else if (data[0] == PLACEHOLDER[0])
 
3433
                data = data.substr(1);
 
3434
            else if (data[data.length - 1] == PLACEHOLDER[0])
 
3435
                data = data.slice(0, -1);
 
3436
            if (data[data.length - 1] == PLACEHOLDER[0])
 
3437
                data = data.slice(0, -1);
 
3438
            
 
3439
            if (data)
 
3440
                host.onTextInput(data);
 
3441
        }
 
3442
    };
 
3443
    var onInput = function(e) {
 
3444
        if (inCompostion)
 
3445
            return;
 
3446
        var data = text.value;
 
3447
        sendText(data);
 
3448
        resetValue();
 
3449
    };
 
3450
 
 
3451
    var onCut = function(e) {
 
3452
        var data = host.getCopyText();
 
3453
        if (!data) {
 
3454
            event.preventDefault(e);
 
3455
            return;
 
3456
        }
 
3457
 
 
3458
        var clipboardData = e.clipboardData || window.clipboardData;
 
3459
 
 
3460
        if (clipboardData && !BROKEN_SETDATA) {
 
3461
            var supported = clipboardData.setData("Text", data);
 
3462
            if (supported) {
 
3463
                host.onCut();
 
3464
                event.preventDefault(e);
 
3465
            }
 
3466
        }
 
3467
 
 
3468
        if (!supported) {
 
3469
            cut = true;
 
3470
            text.value = data;
 
3471
            text.select();
 
3472
            setTimeout(function(){
 
3473
                cut = false;
 
3474
                resetValue();
 
3475
                resetSelection();
 
3476
                host.onCut();
 
3477
            });
 
3478
        }
 
3479
    };
 
3480
 
 
3481
    var onCopy = function(e) {
 
3482
        var data = host.getCopyText();
 
3483
        if (!data) {
 
3484
            event.preventDefault(e);
 
3485
            return;
 
3486
        }
 
3487
 
 
3488
        var clipboardData = e.clipboardData || window.clipboardData;
 
3489
        if (clipboardData && !BROKEN_SETDATA) {
 
3490
            var supported = clipboardData.setData("Text", data);
 
3491
            if (supported) {
 
3492
                host.onCopy();
 
3493
                event.preventDefault(e);
 
3494
            }
 
3495
        }
 
3496
        if (!supported) {
 
3497
            copied = true;
 
3498
            text.value = data;
 
3499
            text.select();
 
3500
            setTimeout(function(){
 
3501
                copied = false;
 
3502
                resetValue();
 
3503
                resetSelection();
 
3504
                host.onCopy();
 
3505
            });
 
3506
        }
 
3507
    };
 
3508
 
 
3509
    var onPaste = function(e) {
 
3510
        var clipboardData = e.clipboardData || window.clipboardData;
 
3511
 
 
3512
        if (clipboardData) {
 
3513
            var data = clipboardData.getData("Text");
 
3514
            if (data)
 
3515
                host.onPaste(data);
 
3516
            if (useragent.isIE)
 
3517
                setTimeout(resetSelection);
 
3518
            event.preventDefault(e);
 
3519
        }
 
3520
        else {
 
3521
            text.value = "";
 
3522
            pasted = true;
 
3523
        }
 
3524
    };
 
3525
 
 
3526
    event.addCommandKeyListener(text, host.onCommandKey.bind(host));
 
3527
 
 
3528
    event.addListener(text, "select", onSelect);
 
3529
 
 
3530
    event.addListener(text, "input", onInput);
 
3531
 
 
3532
    event.addListener(text, "cut", onCut);
 
3533
    event.addListener(text, "copy", onCopy);
 
3534
    event.addListener(text, "paste", onPaste);
 
3535
    if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)){
 
3536
        event.addListener(parentNode, "keydown", function(e) {
 
3537
            if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
 
3538
            return;
 
3539
 
 
3540
            switch (e.keyCode) {
 
3541
                case 67:
 
3542
                    onCopy(e);
 
3543
                    break;
 
3544
                case 86:
 
3545
                    onPaste(e);
 
3546
                    break;
 
3547
                case 88:
 
3548
                    onCut(e);
 
3549
                    break;
 
3550
            }
 
3551
        });
 
3552
    }
 
3553
    var onCompositionStart = function(e) {
 
3554
        inCompostion = true;
 
3555
        host.onCompositionStart();
 
3556
        setTimeout(onCompositionUpdate, 0);
 
3557
    };
 
3558
 
 
3559
    var onCompositionUpdate = function() {
 
3560
        if (!inCompostion) return;
 
3561
        host.onCompositionUpdate(text.value);
 
3562
    };
 
3563
    
 
3564
    var lastCompositionTime = -1;
 
3565
    var onCompositionEnd = function(e) {
 
3566
        inCompostion = false;
 
3567
        host.onCompositionEnd();
 
3568
        lastCompositionTime = Date.now();
 
3569
    };
 
3570
 
 
3571
    var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
 
3572
 
 
3573
    event.addListener(text, "compositionstart", onCompositionStart);
 
3574
    event.addListener(text, useragent.isGecko ? "text" : "keyup", function(){syncComposition.schedule()});
 
3575
    event.addListener(text, "compositionend", onCompositionEnd);
 
3576
 
 
3577
    this.getElement = function() {
 
3578
        return text;
 
3579
    };
 
3580
 
 
3581
    this.setReadOnly = function(readOnly) {
 
3582
       text.readOnly = readOnly;
 
3583
    };
 
3584
 
 
3585
    this.onContextMenu = function(e) {
 
3586
        if (!tempStyle)
 
3587
            tempStyle = text.style.cssText;
 
3588
 
 
3589
        text.style.cssText = "z-index:100000;" + (useragent.isIE ? "opacity:0.1;" : "");
 
3590
 
 
3591
        resetSelection(host.selection.isEmpty());
 
3592
        host._emit("nativecontextmenu", {target: host});
 
3593
        var rect = host.container.getBoundingClientRect();
 
3594
        var style = dom.computedStyle(host.container);
 
3595
        var top = rect.top + (parseInt(style.borderTopWidth) || 0);
 
3596
        var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
 
3597
        var maxTop = rect.bottom - top - text.clientHeight;
 
3598
        var move = function(e) {
 
3599
            text.style.left = e.clientX - left - 2 + "px";
 
3600
            text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
 
3601
        }; 
 
3602
        move(e);
 
3603
 
 
3604
        if (e.type != "mousedown")
 
3605
            return;
 
3606
 
 
3607
        if (host.renderer.$keepTextAreaAtCursor)
 
3608
            host.renderer.$keepTextAreaAtCursor = null;
 
3609
        if (useragent.isWin)
 
3610
            event.capture(host.container, move, onContextMenuClose);
 
3611
    };
 
3612
 
 
3613
    this.onContextMenuClose = onContextMenuClose;
 
3614
    function onContextMenuClose() {
 
3615
        setTimeout(function () {
 
3616
            if (tempStyle) {
 
3617
                text.style.cssText = tempStyle;
 
3618
                tempStyle = '';
 
3619
            }
 
3620
            if (host.renderer.$keepTextAreaAtCursor == null) {
 
3621
                host.renderer.$keepTextAreaAtCursor = true;
 
3622
                host.renderer.$moveTextAreaToCursor();
 
3623
            }
 
3624
        }, 0);
 
3625
    }
 
3626
    if (!useragent.isGecko) {
 
3627
        event.addListener(text, "contextmenu", function(e) {
 
3628
            host.textInput.onContextMenu(e);
 
3629
            onContextMenuClose();
 
3630
        });
 
3631
    }
 
3632
};
 
3633
 
 
3634
exports.TextInput = TextInput;
 
3635
});
 
3636
 
 
3637
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', 'ace/config'], function(require, exports, module) {
 
3638
 
 
3639
 
 
3640
var event = require("../lib/event");
 
3641
var useragent = require("../lib/useragent");
 
3642
var DefaultHandlers = require("./default_handlers").DefaultHandlers;
 
3643
var DefaultGutterHandler = require("./default_gutter_handler").GutterHandler;
 
3644
var MouseEvent = require("./mouse_event").MouseEvent;
 
3645
var DragdropHandler = require("./dragdrop").DragdropHandler;
 
3646
var config = require("../config");
 
3647
 
 
3648
var MouseHandler = function(editor) {
 
3649
    this.editor = editor;
 
3650
 
 
3651
    new DefaultHandlers(this);
 
3652
    new DefaultGutterHandler(this);
 
3653
    new DragdropHandler(this);
 
3654
 
 
3655
    event.addListener(editor.container, "mousedown", function(e) {
 
3656
        editor.focus();
 
3657
        return event.preventDefault(e);
 
3658
    });
 
3659
 
 
3660
    var mouseTarget = editor.renderer.getMouseEventTarget();
 
3661
    event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
 
3662
    event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"));
 
3663
    event.addMultiMouseDownListener(mouseTarget, [300, 300, 250], this, "onMouseEvent");
 
3664
    event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"));
 
3665
 
 
3666
    var gutterEl = editor.renderer.$gutter;
 
3667
    event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"));
 
3668
    event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
 
3669
    event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"));
 
3670
    event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"));
 
3671
};
 
3672
 
 
3673
(function() {
 
3674
    this.onMouseEvent = function(name, e) {
 
3675
        this.editor._emit(name, new MouseEvent(e, this.editor));
 
3676
    };
 
3677
 
 
3678
    this.onMouseMove = function(name, e) {
 
3679
        var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;
 
3680
        if (!listeners || !listeners.length)
 
3681
            return;
 
3682
 
 
3683
        this.editor._emit(name, new MouseEvent(e, this.editor));
 
3684
    };
 
3685
 
 
3686
    this.onMouseWheel = function(name, e) {
 
3687
        var mouseEvent = new MouseEvent(e, this.editor);
 
3688
        mouseEvent.speed = this.$scrollSpeed * 2;
 
3689
        mouseEvent.wheelX = e.wheelX;
 
3690
        mouseEvent.wheelY = e.wheelY;
 
3691
 
 
3692
        this.editor._emit(name, mouseEvent);
 
3693
    };
 
3694
 
 
3695
    this.setState = function(state) {
 
3696
        this.state = state;
 
3697
    };
 
3698
 
 
3699
    this.captureMouse = function(ev, state) {
 
3700
        if (state)
 
3701
            this.setState(state);
 
3702
 
 
3703
        this.x = ev.x;
 
3704
        this.y = ev.y;
 
3705
        
 
3706
        this.isMousePressed = true;
 
3707
        var renderer = this.editor.renderer;
 
3708
        if (renderer.$keepTextAreaAtCursor)
 
3709
            renderer.$keepTextAreaAtCursor = null;
 
3710
 
 
3711
        var self = this;
 
3712
        var onMouseMove = function(e) {
 
3713
            self.x = e.clientX;
 
3714
            self.y = e.clientY;
 
3715
        };
 
3716
 
 
3717
        var onCaptureEnd = function(e) {
 
3718
            clearInterval(timerId);
 
3719
            onCaptureInterval();
 
3720
            self[self.state + "End"] && self[self.state + "End"](e);
 
3721
            self.$clickSelection = null;
 
3722
            if (renderer.$keepTextAreaAtCursor == null) {
 
3723
                renderer.$keepTextAreaAtCursor = true;
 
3724
                renderer.$moveTextAreaToCursor();
 
3725
            }
 
3726
            self.isMousePressed = false;
 
3727
        };
 
3728
 
 
3729
        var onCaptureInterval = function() {
 
3730
            self[self.state] && self[self.state]();
 
3731
        };
 
3732
        
 
3733
        if (useragent.isOldIE && ev.domEvent.type == "dblclick") {
 
3734
            return setTimeout(function() {onCaptureEnd(ev.domEvent);});
 
3735
        }
 
3736
 
 
3737
        event.capture(this.editor.container, onMouseMove, onCaptureEnd);
 
3738
        var timerId = setInterval(onCaptureInterval, 20);
 
3739
    };
 
3740
}).call(MouseHandler.prototype);
 
3741
 
 
3742
config.defineOptions(MouseHandler.prototype, "mouseHandler", {
 
3743
    scrollSpeed: {initialValue: 1},
 
3744
    dragDelay: {initialValue: 150},
 
3745
    focusTimout: {initialValue: 0}
 
3746
});
 
3747
 
 
3748
 
 
3749
exports.MouseHandler = MouseHandler;
 
3750
});
 
3751
 
 
3752
define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/useragent'], function(require, exports, module) {
 
3753
 
 
3754
 
 
3755
var dom = require("../lib/dom");
 
3756
var useragent = require("../lib/useragent");
 
3757
 
 
3758
var DRAG_OFFSET = 0; // pixels
 
3759
 
 
3760
function DefaultHandlers(mouseHandler) {
 
3761
    mouseHandler.$clickSelection = null;
 
3762
 
 
3763
    var editor = mouseHandler.editor;
 
3764
    editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
 
3765
    editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
 
3766
    editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
 
3767
    editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
 
3768
    editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler));
 
3769
 
 
3770
    var exports = ["select", "startSelect", "drag", "dragEnd", "dragWait",
 
3771
        "dragWaitEnd", "startDrag", "focusWait"];
 
3772
 
 
3773
    exports.forEach(function(x) {
 
3774
        mouseHandler[x] = this[x];
 
3775
    }, this);
 
3776
 
 
3777
    mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
 
3778
    mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
 
3779
}
 
3780
 
 
3781
(function() {
 
3782
 
 
3783
    this.onMouseDown = function(ev) {
 
3784
        var inSelection = ev.inSelection();
 
3785
        var pos = ev.getDocumentPosition();
 
3786
        this.mousedownEvent = ev;
 
3787
        var editor = this.editor;
 
3788
 
 
3789
        var button = ev.getButton();
 
3790
        if (button !== 0) {
 
3791
            var selectionRange = editor.getSelectionRange();
 
3792
            var selectionEmpty = selectionRange.isEmpty();
 
3793
 
 
3794
            if (selectionEmpty) {
 
3795
                editor.moveCursorToPosition(pos);
 
3796
                editor.selection.clearSelection();
 
3797
            }
 
3798
            editor.textInput.onContextMenu(ev.domEvent);
 
3799
            return; // stopping event here breaks contextmenu on ff mac
 
3800
        }
 
3801
        if (inSelection && !editor.isFocused()) {
 
3802
            editor.focus();
 
3803
            if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
 
3804
                this.setState("focusWait");
 
3805
                this.captureMouse(ev);
 
3806
                return ev.preventDefault();
 
3807
            }
 
3808
        }
 
3809
 
 
3810
        if (!inSelection || this.$clickSelection || ev.getShiftKey() || editor.inMultiSelectMode) {
 
3811
            this.startSelect(pos);
 
3812
        } else if (inSelection) {
 
3813
            this.mousedownEvent.time = (new Date()).getTime();
 
3814
            this.setState("dragWait");
 
3815
        }
 
3816
 
 
3817
        this.captureMouse(ev);
 
3818
        return ev.preventDefault();
 
3819
    };
 
3820
 
 
3821
    this.startSelect = function(pos) {
 
3822
        pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
 
3823
        if (this.mousedownEvent.getShiftKey()) {
 
3824
            this.editor.selection.selectToPosition(pos);
 
3825
        }
 
3826
        else if (!this.$clickSelection) {
 
3827
            this.editor.moveCursorToPosition(pos);
 
3828
            this.editor.selection.clearSelection();
 
3829
        }
 
3830
        this.setState("select");
 
3831
    };
 
3832
 
 
3833
    this.select = function() {
 
3834
        var anchor, editor = this.editor;
 
3835
        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
 
3836
 
 
3837
        if (this.$clickSelection) {
 
3838
            var cmp = this.$clickSelection.comparePoint(cursor);
 
3839
 
 
3840
            if (cmp == -1) {
 
3841
                anchor = this.$clickSelection.end;
 
3842
            } else if (cmp == 1) {
 
3843
                anchor = this.$clickSelection.start;
 
3844
            } else {
 
3845
                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
 
3846
                cursor = orientedRange.cursor;
 
3847
                anchor = orientedRange.anchor;
 
3848
            }
 
3849
            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
 
3850
        }
 
3851
        editor.selection.selectToPosition(cursor);
 
3852
 
 
3853
        editor.renderer.scrollCursorIntoView();
 
3854
    };
 
3855
 
 
3856
    this.extendSelectionBy = function(unitName) {
 
3857
        var anchor, editor = this.editor;
 
3858
        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
 
3859
        var range = editor.selection[unitName](cursor.row, cursor.column);
 
3860
 
 
3861
        if (this.$clickSelection) {
 
3862
            var cmpStart = this.$clickSelection.comparePoint(range.start);
 
3863
            var cmpEnd = this.$clickSelection.comparePoint(range.end);
 
3864
 
 
3865
            if (cmpStart == -1 && cmpEnd <= 0) {
 
3866
                anchor = this.$clickSelection.end;
 
3867
                if (range.end.row != cursor.row || range.end.column != cursor.column)
 
3868
                    cursor = range.start;
 
3869
            } else if (cmpEnd == 1 && cmpStart >= 0) {
 
3870
                anchor = this.$clickSelection.start;
 
3871
                if (range.start.row != cursor.row || range.start.column != cursor.column)
 
3872
                    cursor = range.end;
 
3873
            } else if (cmpStart == -1 && cmpEnd == 1) {
 
3874
                cursor = range.end;
 
3875
                anchor = range.start;
 
3876
            } else {
 
3877
                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
 
3878
                cursor = orientedRange.cursor;
 
3879
                anchor = orientedRange.anchor;
 
3880
            }
 
3881
            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
 
3882
        }
 
3883
        editor.selection.selectToPosition(cursor);
 
3884
 
 
3885
        editor.renderer.scrollCursorIntoView();
 
3886
    };
 
3887
 
 
3888
    this.startDrag = function() {
 
3889
        var editor = this.editor;
 
3890
        this.setState("drag");
 
3891
        this.dragRange = editor.getSelectionRange();
 
3892
        var style = editor.getSelectionStyle();
 
3893
        this.dragSelectionMarker = editor.session.addMarker(this.dragRange, "ace_selection", style);
 
3894
        editor.clearSelection();
 
3895
        dom.addCssClass(editor.container, "ace_dragging");
 
3896
        if (!this.$dragKeybinding) {
 
3897
            this.$dragKeybinding = {
 
3898
                handleKeyboard: function(data, hashId, keyString, keyCode) {
 
3899
                    if (keyString == "esc")
 
3900
                        return {command: this.command};
 
3901
                },
 
3902
                command: {
 
3903
                    exec: function(editor) {
 
3904
                        var self = editor.$mouseHandler;
 
3905
                        self.dragCursor = null;
 
3906
                        self.dragEnd();
 
3907
                        self.startSelect();
 
3908
                    }
 
3909
                }
 
3910
            }
 
3911
        }
 
3912
 
 
3913
        editor.keyBinding.addKeyboardHandler(this.$dragKeybinding);
 
3914
    };
 
3915
 
 
3916
    this.focusWait = function() {
 
3917
        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
 
3918
        var time = (new Date()).getTime();
 
3919
 
 
3920
        if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
 
3921
            this.startSelect(this.mousedownEvent.getDocumentPosition());
 
3922
    };
 
3923
 
 
3924
    this.dragWait = function(e) {
 
3925
        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
 
3926
        var time = (new Date()).getTime();
 
3927
        var editor = this.editor;
 
3928
 
 
3929
        if (distance > DRAG_OFFSET) {
 
3930
            this.startSelect(this.mousedownEvent.getDocumentPosition());
 
3931
        } else if (time - this.mousedownEvent.time > editor.$mouseHandler.$dragDelay) {
 
3932
            this.startDrag();
 
3933
        }
 
3934
    };
 
3935
 
 
3936
    this.dragWaitEnd = function(e) {
 
3937
        this.mousedownEvent.domEvent = e;
 
3938
        this.startSelect();
 
3939
    };
 
3940
 
 
3941
    this.drag = function() {
 
3942
        var editor = this.editor;
 
3943
        this.dragCursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
 
3944
        editor.moveCursorToPosition(this.dragCursor);
 
3945
        editor.renderer.scrollCursorIntoView();
 
3946
    };
 
3947
 
 
3948
    this.dragEnd = function(e) {
 
3949
        var editor = this.editor;
 
3950
        var dragCursor = this.dragCursor;
 
3951
        var dragRange = this.dragRange;
 
3952
        dom.removeCssClass(editor.container, "ace_dragging");
 
3953
        editor.session.removeMarker(this.dragSelectionMarker);
 
3954
        editor.keyBinding.removeKeyboardHandler(this.$dragKeybinding);
 
3955
 
 
3956
        if (!dragCursor)
 
3957
            return;
 
3958
 
 
3959
        editor.clearSelection();
 
3960
        if (e && (e.ctrlKey || e.altKey)) {
 
3961
            var session = editor.session;
 
3962
            var newRange = dragRange;
 
3963
            newRange.end = session.insert(dragCursor, session.getTextRange(dragRange));
 
3964
            newRange.start = dragCursor;
 
3965
        } else if (dragRange.contains(dragCursor.row, dragCursor.column)) {
 
3966
            return;
 
3967
        } else {
 
3968
            var newRange = editor.moveText(dragRange, dragCursor);
 
3969
        }
 
3970
 
 
3971
        if (!newRange)
 
3972
            return;
 
3973
 
 
3974
        editor.selection.setSelectionRange(newRange);
 
3975
    };
 
3976
 
 
3977
    this.onDoubleClick = function(ev) {
 
3978
        var pos = ev.getDocumentPosition();
 
3979
        var editor = this.editor;
 
3980
        var session = editor.session;
 
3981
 
 
3982
        var range = session.getBracketRange(pos);
 
3983
        if (range) {
 
3984
            if (range.isEmpty()) {
 
3985
                range.start.column--;
 
3986
                range.end.column++;
 
3987
            }
 
3988
            this.$clickSelection = range;
 
3989
            this.setState("select");
 
3990
            return;
 
3991
        }
 
3992
 
 
3993
        this.$clickSelection = editor.selection.getWordRange(pos.row, pos.column);
 
3994
        this.setState("selectByWords");
 
3995
    };
 
3996
 
 
3997
    this.onTripleClick = function(ev) {
 
3998
        var pos = ev.getDocumentPosition();
 
3999
        var editor = this.editor;
 
4000
 
 
4001
        this.setState("selectByLines");
 
4002
        this.$clickSelection = editor.selection.getLineRange(pos.row);
 
4003
    };
 
4004
 
 
4005
    this.onQuadClick = function(ev) {
 
4006
        var editor = this.editor;
 
4007
 
 
4008
        editor.selectAll();
 
4009
        this.$clickSelection = editor.getSelectionRange();
 
4010
        this.setState("null");
 
4011
    };
 
4012
 
 
4013
    this.onMouseWheel = function(ev) {
 
4014
        if (ev.getShiftKey() || ev.getAccelKey())
 
4015
            return;
 
4016
        var t = ev.domEvent.timeStamp;
 
4017
        var dt = t - (this.$lastScrollTime||0);
 
4018
        
 
4019
        var editor = this.editor;
 
4020
        var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
 
4021
        if (isScrolable || dt < 200) {
 
4022
            this.$lastScrollTime = t;
 
4023
            editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
 
4024
            return ev.stop();
 
4025
        }
 
4026
    };
 
4027
 
 
4028
}).call(DefaultHandlers.prototype);
 
4029
 
 
4030
exports.DefaultHandlers = DefaultHandlers;
 
4031
 
 
4032
function calcDistance(ax, ay, bx, by) {
 
4033
    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
 
4034
}
 
4035
 
 
4036
function calcRangeOrientation(range, cursor) {
 
4037
    if (range.start.row == range.end.row)
 
4038
        var cmp = 2 * cursor.column - range.start.column - range.end.column;
 
4039
    else
 
4040
        var cmp = 2 * cursor.row - range.start.row - range.end.row;
 
4041
 
 
4042
    if (cmp < 0)
 
4043
        return {cursor: range.start, anchor: range.end};
 
4044
    else
 
4045
        return {cursor: range.end, anchor: range.start};
 
4046
}
 
4047
 
 
4048
});
 
4049
 
 
4050
define('ace/mouse/default_gutter_handler', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event'], function(require, exports, module) {
 
4051
 
 
4052
var dom = require("../lib/dom");
 
4053
var event = require("../lib/event");
 
4054
 
 
4055
function GutterHandler(mouseHandler) {
 
4056
    var editor = mouseHandler.editor;
 
4057
    var gutter = editor.renderer.$gutterLayer;
 
4058
 
 
4059
    mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
 
4060
        if (!editor.isFocused())
 
4061
            return;
 
4062
        var gutterRegion = gutter.getRegion(e);
 
4063
 
 
4064
        if (gutterRegion == "foldWidgets")
 
4065
            return;
 
4066
 
 
4067
        var row = e.getDocumentPosition().row;
 
4068
        var selection = editor.session.selection;
 
4069
 
 
4070
        if (e.getShiftKey())
 
4071
            selection.selectTo(row, 0);
 
4072
        else {
 
4073
            if (e.domEvent.detail == 2) {
 
4074
                editor.selectAll();
 
4075
                return e.preventDefault();
 
4076
            }
 
4077
            mouseHandler.$clickSelection = editor.selection.getLineRange(row);
 
4078
        }
 
4079
        mouseHandler.captureMouse(e, "selectByLines");
 
4080
        return e.preventDefault();
 
4081
    });
 
4082
 
 
4083
 
 
4084
    var tooltipTimeout, mouseEvent, tooltip, tooltipAnnotation;
 
4085
    function createTooltip() {
 
4086
        tooltip = dom.createElement("div");
 
4087
        tooltip.className = "ace_gutter-tooltip";
 
4088
        tooltip.style.display = "none";
 
4089
        editor.container.appendChild(tooltip);
 
4090
    }
 
4091
 
 
4092
    function showTooltip() {
 
4093
        if (!tooltip) {
 
4094
            createTooltip();
 
4095
        }
 
4096
        var row = mouseEvent.getDocumentPosition().row;
 
4097
        var annotation = gutter.$annotations[row];
 
4098
        if (!annotation)
 
4099
            return hideTooltip();
 
4100
 
 
4101
        var maxRow = editor.session.getLength();
 
4102
        if (row == maxRow) {
 
4103
            var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;
 
4104
            var pos = mouseEvent.$pos;
 
4105
            if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))
 
4106
                return hideTooltip();
 
4107
        }
 
4108
 
 
4109
        if (tooltipAnnotation == annotation)
 
4110
            return;
 
4111
        tooltipAnnotation = annotation.text.join("<br/>");
 
4112
 
 
4113
        tooltip.style.display = "block";
 
4114
        tooltip.innerHTML = tooltipAnnotation;
 
4115
        editor.on("mousewheel", hideTooltip);
 
4116
 
 
4117
        moveTooltip(mouseEvent);
 
4118
    }
 
4119
 
 
4120
    function hideTooltip() {
 
4121
        if (tooltipTimeout)
 
4122
            tooltipTimeout = clearTimeout(tooltipTimeout);
 
4123
        if (tooltipAnnotation) {
 
4124
            tooltip.style.display = "none";
 
4125
            tooltipAnnotation = null;
 
4126
            editor.removeEventListener("mousewheel", hideTooltip);
 
4127
        }
 
4128
    }
 
4129
 
 
4130
    function moveTooltip(e) {
 
4131
        var rect = editor.renderer.$gutter.getBoundingClientRect();
 
4132
        tooltip.style.left = e.x + 15 + "px";
 
4133
        if (e.y + 3 * editor.renderer.lineHeight + 15 < rect.bottom) {
 
4134
            tooltip.style.bottom =  "";
 
4135
            tooltip.style.top =  e.y + 15 + "px";
 
4136
        } else {
 
4137
            tooltip.style.top =  "";
 
4138
            tooltip.style.bottom = rect.bottom - e.y + 5 + "px";
 
4139
        }
 
4140
    }
 
4141
 
 
4142
    mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) {
 
4143
        var target = e.domEvent.target || e.domEvent.srcElement;
 
4144
        if (dom.hasCssClass(target, "ace_fold-widget"))
 
4145
            return hideTooltip();
 
4146
 
 
4147
        if (tooltipAnnotation)
 
4148
            moveTooltip(e);
 
4149
 
 
4150
        mouseEvent = e;
 
4151
        if (tooltipTimeout)
 
4152
            return;
 
4153
        tooltipTimeout = setTimeout(function() {
 
4154
            tooltipTimeout = null;
 
4155
            if (mouseEvent && !mouseHandler.isMousePressed)
 
4156
                showTooltip();
 
4157
            else
 
4158
                hideTooltip();
 
4159
        }, 50);
 
4160
    });
 
4161
 
 
4162
    event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
 
4163
        mouseEvent = null;
 
4164
        if (!tooltipAnnotation || tooltipTimeout)
 
4165
            return;
 
4166
 
 
4167
        tooltipTimeout = setTimeout(function() {
 
4168
            tooltipTimeout = null;
 
4169
            hideTooltip();
 
4170
        }, 50);
 
4171
    });
 
4172
 
 
4173
}
 
4174
 
 
4175
exports.GutterHandler = GutterHandler;
 
4176
 
 
4177
});
 
4178
 
 
4179
define('ace/mouse/mouse_event', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
 
4180
 
 
4181
 
 
4182
var event = require("../lib/event");
 
4183
var useragent = require("../lib/useragent");
 
4184
var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
 
4185
    this.domEvent = domEvent;
 
4186
    this.editor = editor;
 
4187
    
 
4188
    this.x = this.clientX = domEvent.clientX;
 
4189
    this.y = this.clientY = domEvent.clientY;
 
4190
 
 
4191
    this.$pos = null;
 
4192
    this.$inSelection = null;
 
4193
    
 
4194
    this.propagationStopped = false;
 
4195
    this.defaultPrevented = false;
 
4196
};
 
4197
 
 
4198
(function() {  
 
4199
    
 
4200
    this.stopPropagation = function() {
 
4201
        event.stopPropagation(this.domEvent);
 
4202
        this.propagationStopped = true;
 
4203
    };
 
4204
    
 
4205
    this.preventDefault = function() {
 
4206
        event.preventDefault(this.domEvent);
 
4207
        this.defaultPrevented = true;
 
4208
    };
 
4209
    
 
4210
    this.stop = function() {
 
4211
        this.stopPropagation();
 
4212
        this.preventDefault();
 
4213
    };
 
4214
    this.getDocumentPosition = function() {
 
4215
        if (this.$pos)
 
4216
            return this.$pos;
 
4217
        
 
4218
        this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
 
4219
        return this.$pos;
 
4220
    };
 
4221
    this.inSelection = function() {
 
4222
        if (this.$inSelection !== null)
 
4223
            return this.$inSelection;
 
4224
            
 
4225
        var editor = this.editor;
 
4226
        
 
4227
        if (editor.getReadOnly()) {
 
4228
            this.$inSelection = false;
 
4229
        }
 
4230
        else {
 
4231
            var selectionRange = editor.getSelectionRange();
 
4232
            if (selectionRange.isEmpty())
 
4233
                this.$inSelection = false;
 
4234
            else {
 
4235
                var pos = this.getDocumentPosition();
 
4236
                this.$inSelection = selectionRange.contains(pos.row, pos.column);
 
4237
            }
 
4238
        }
 
4239
        return this.$inSelection;
 
4240
    };
 
4241
    this.getButton = function() {
 
4242
        return event.getButton(this.domEvent);
 
4243
    };
 
4244
    this.getShiftKey = function() {
 
4245
        return this.domEvent.shiftKey;
 
4246
    };
 
4247
    
 
4248
    this.getAccelKey = useragent.isMac
 
4249
        ? function() { return this.domEvent.metaKey; }
 
4250
        : function() { return this.domEvent.ctrlKey; };
 
4251
    
 
4252
}).call(MouseEvent.prototype);
 
4253
 
 
4254
});
 
4255
 
 
4256
define('ace/mouse/dragdrop', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
 
4257
 
 
4258
 
 
4259
var event = require("../lib/event");
 
4260
 
 
4261
var DragdropHandler = function(mouseHandler) {
 
4262
    var editor = mouseHandler.editor;
 
4263
    var dragSelectionMarker, x, y;
 
4264
    var timerId, range;
 
4265
    var dragCursor, counter = 0;
 
4266
 
 
4267
    var mouseTarget = editor.container;
 
4268
    event.addListener(mouseTarget, "dragenter", function(e) {
 
4269
        if (editor.getReadOnly())
 
4270
            return;
 
4271
        var types = e.dataTransfer.types;
 
4272
        if (types && Array.prototype.indexOf.call(types, "text/plain") === -1)
 
4273
            return;
 
4274
        if (!dragSelectionMarker)
 
4275
            addDragMarker();
 
4276
        counter++;
 
4277
        return event.preventDefault(e);
 
4278
    });
 
4279
 
 
4280
    event.addListener(mouseTarget, "dragover", function(e) {
 
4281
        if (editor.getReadOnly())
 
4282
            return;
 
4283
        var types = e.dataTransfer.types;
 
4284
        if (types && Array.prototype.indexOf.call(types, "text/plain") === -1)
 
4285
            return;
 
4286
        if (onMouseMoveTimer !== null)
 
4287
            onMouseMoveTimer = null;
 
4288
        x = e.clientX;
 
4289
        y = e.clientY;
 
4290
        return event.preventDefault(e);
 
4291
    });
 
4292
 
 
4293
    var onDragInterval =  function() {
 
4294
        dragCursor = editor.renderer.screenToTextCoordinates(x, y);
 
4295
        editor.moveCursorToPosition(dragCursor);
 
4296
        editor.renderer.scrollCursorIntoView();
 
4297
    };
 
4298
 
 
4299
    event.addListener(mouseTarget, "dragleave", function(e) {
 
4300
        counter--;
 
4301
        if (counter <= 0 && dragSelectionMarker) {
 
4302
            clearDragMarker();
 
4303
            return event.preventDefault(e);
 
4304
        }
 
4305
    });
 
4306
 
 
4307
    event.addListener(mouseTarget, "drop", function(e) {
 
4308
        if (!dragSelectionMarker)
 
4309
            return;
 
4310
        range.end = editor.session.insert(dragCursor, e.dataTransfer.getData('Text'));
 
4311
        range.start = dragCursor;
 
4312
        clearDragMarker();
 
4313
        editor.focus();
 
4314
        return event.preventDefault(e);
 
4315
    });
 
4316
 
 
4317
    function addDragMarker() {
 
4318
        range = editor.selection.toOrientedRange();
 
4319
        dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle());
 
4320
        editor.clearSelection();
 
4321
        clearInterval(timerId);
 
4322
        timerId = setInterval(onDragInterval, 20);
 
4323
        counter = 0;
 
4324
        event.addListener(document, "mousemove", onMouseMove);
 
4325
    }
 
4326
    function clearDragMarker() {
 
4327
        clearInterval(timerId);
 
4328
        editor.session.removeMarker(dragSelectionMarker);
 
4329
        dragSelectionMarker = null;
 
4330
        editor.selection.fromOrientedRange(range);
 
4331
        counter = 0;
 
4332
        event.removeListener(document, "mousemove", onMouseMove);
 
4333
    }
 
4334
    var onMouseMoveTimer = null;
 
4335
    function onMouseMove() {
 
4336
        if (onMouseMoveTimer == null) {
 
4337
            onMouseMoveTimer = setTimeout(function() {
 
4338
                if (onMouseMoveTimer != null && dragSelectionMarker)
 
4339
                    clearDragMarker();
 
4340
            }, 20);
 
4341
        }
 
4342
    }
 
4343
};
 
4344
 
 
4345
exports.DragdropHandler = DragdropHandler;
 
4346
});
 
4347
 
 
4348
define('ace/config', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/lib/net', 'ace/lib/event_emitter'], function(require, exports, module) {
 
4349
"no use strict";
 
4350
 
 
4351
var lang = require("./lib/lang");
 
4352
var oop = require("./lib/oop");
 
4353
var net = require("./lib/net");
 
4354
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
4355
 
 
4356
var global = (function() {
 
4357
    return this;
 
4358
})();
 
4359
 
 
4360
var options = {
 
4361
    packaged: false,
 
4362
    workerPath: null,
 
4363
    modePath: null,
 
4364
    themePath: null,
 
4365
    basePath: "",
 
4366
    suffix: ".js",
 
4367
    $moduleUrls: {}
 
4368
};
 
4369
 
 
4370
exports.get = function(key) {
 
4371
    if (!options.hasOwnProperty(key))
 
4372
        throw new Error("Unknown config key: " + key);
 
4373
 
 
4374
    return options[key];
 
4375
};
 
4376
 
 
4377
exports.set = function(key, value) {
 
4378
    if (!options.hasOwnProperty(key))
 
4379
        throw new Error("Unknown config key: " + key);
 
4380
 
 
4381
    options[key] = value;
 
4382
};
 
4383
 
 
4384
exports.all = function() {
 
4385
    return lang.copyObject(options);
 
4386
};
 
4387
oop.implement(exports, EventEmitter);
 
4388
 
 
4389
exports.moduleUrl = function(name, component) {
 
4390
    if (options.$moduleUrls[name])
 
4391
        return options.$moduleUrls[name];
 
4392
 
 
4393
    var parts = name.split("/");
 
4394
    component = component || parts[parts.length - 2] || "";
 
4395
    var base = parts[parts.length - 1].replace(component, "").replace(/(^[\-_])|([\-_]$)/, "");
 
4396
 
 
4397
    if (!base && parts.length > 1)
 
4398
        base = parts[parts.length - 2];
 
4399
    var path = options[component + "Path"];
 
4400
    if (path == null)
 
4401
        path = options.basePath;
 
4402
    if (path && path.slice(-1) != "/")
 
4403
        path += "/";
 
4404
    return path + component + "-" + base + this.get("suffix");
 
4405
};
 
4406
 
 
4407
exports.setModuleUrl = function(name, subst) {
 
4408
    return options.$moduleUrls[name] = subst;
 
4409
};
 
4410
 
 
4411
exports.loadModule = function(moduleName, onLoad) {
 
4412
    var module, moduleType;
 
4413
    if (Array.isArray(moduleName)) {
 
4414
        moduleType = moduleName[0];
 
4415
        moduleName = moduleName[1];
 
4416
    }
 
4417
    try {
 
4418
        module = require(moduleName);
 
4419
    } catch (e) {};
 
4420
    if (module)
 
4421
        return onLoad && onLoad(module);
 
4422
 
 
4423
    var afterLoad = function() {
 
4424
        require([moduleName], function(module) {
 
4425
            exports._emit("load.module", {name: moduleName, module: module});
 
4426
            onLoad && onLoad(module);
 
4427
        });
 
4428
    };
 
4429
 
 
4430
    if (!exports.get("packaged"))
 
4431
        return afterLoad();
 
4432
    net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
 
4433
};
 
4434
exports.init = function() {
 
4435
    options.packaged = require.packaged || module.packaged || (global.define && define.packaged);
 
4436
 
 
4437
    if (!global.document)
 
4438
        return "";
 
4439
 
 
4440
    var scriptOptions = {};
 
4441
    var scriptUrl = "";
 
4442
 
 
4443
    var scripts = document.getElementsByTagName("script");
 
4444
    for (var i=0; i<scripts.length; i++) {
 
4445
        var script = scripts[i];
 
4446
 
 
4447
        var src = script.src || script.getAttribute("src");
 
4448
        if (!src)
 
4449
            continue;
 
4450
 
 
4451
        var attributes = script.attributes;
 
4452
        for (var j=0, l=attributes.length; j < l; j++) {
 
4453
            var attr = attributes[j];
 
4454
            if (attr.name.indexOf("data-ace-") === 0) {
 
4455
                scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, ""))] = attr.value;
 
4456
            }
 
4457
        }
 
4458
 
 
4459
        var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);
 
4460
        if (m)
 
4461
            scriptUrl = m[1];
 
4462
    }
 
4463
 
 
4464
    if (scriptUrl) {
 
4465
        scriptOptions.base = scriptOptions.base || scriptUrl;
 
4466
        scriptOptions.packaged = true;
 
4467
    }
 
4468
 
 
4469
    scriptOptions.basePath = scriptOptions.base;
 
4470
    scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
 
4471
    scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
 
4472
    scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
 
4473
    delete scriptOptions.base;
 
4474
 
 
4475
    for (var key in scriptOptions)
 
4476
        if (typeof scriptOptions[key] !== "undefined")
 
4477
            exports.set(key, scriptOptions[key]);
 
4478
};
 
4479
 
 
4480
function deHyphenate(str) {
 
4481
    return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
 
4482
}
 
4483
 
 
4484
var optionsProvider = {
 
4485
    setOptions: function(optList) {
 
4486
        Object.keys(optList).forEach(function(key) {
 
4487
            this.setOption(key, optList[key]);
 
4488
        }, this);
 
4489
    },
 
4490
    getOptions: function(a) {
 
4491
        var b = {};
 
4492
        Object.keys(a).forEach(function(key) {
 
4493
            b[key] = this.getOption(key);
 
4494
        }, this);
 
4495
        return b;
 
4496
    },
 
4497
    setOption: function(name, value) {
 
4498
        if (this["$" + name] === value)
 
4499
            return;
 
4500
        var opt = this.$options[name];
 
4501
        if (!opt)
 
4502
            return undefined;
 
4503
        if (opt.forwardTo)
 
4504
            return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);
 
4505
 
 
4506
        if (!opt.handlesSet)
 
4507
            this["$" + name] = value;
 
4508
        if (opt && opt.set)
 
4509
            opt.set.call(this, value);
 
4510
    },
 
4511
    getOption: function(name) {
 
4512
        var opt = this.$options[name];
 
4513
        if (!opt)
 
4514
            return undefined;
 
4515
        if (opt.forwardTo)
 
4516
            return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);
 
4517
        return opt && opt.get ? opt.get.call(this) : this["$" + name];
 
4518
    }
 
4519
};
 
4520
 
 
4521
var defaultOptions = {};
 
4522
exports.defineOptions = function(obj, path, options) {
 
4523
    if (!obj.$options)
 
4524
        defaultOptions[path] = obj.$options = {};
 
4525
 
 
4526
    Object.keys(options).forEach(function(key) {
 
4527
        var opt = options[key];
 
4528
        if (typeof opt == "string")
 
4529
            opt = {forwardTo: opt};
 
4530
 
 
4531
        opt.name || (opt.name = key);
 
4532
        obj.$options[opt.name] = opt;
 
4533
        if ("initialValue" in opt)
 
4534
            obj["$" + opt.name] = opt.initialValue;
 
4535
    });
 
4536
    oop.implement(obj, optionsProvider);
 
4537
 
 
4538
    return this;
 
4539
};
 
4540
 
 
4541
exports.resetOptions = function(obj) {
 
4542
    Object.keys(obj.$options).forEach(function(key) {
 
4543
        var opt = obj.$options[key];
 
4544
        if ("value" in opt)
 
4545
            obj.setOption(key, opt.value);
 
4546
    });
 
4547
};
 
4548
 
 
4549
exports.setDefaultValue = function(path, name, value) {
 
4550
    var opts = defaultOptions[path] || (defaultOptions[path] = {});
 
4551
    if (opts[name]) {
 
4552
        if (opts.forwardTo)
 
4553
            exports.setDefaultValue(opts.forwardTo, name, value)
 
4554
        else
 
4555
            opts[name].value = value;
 
4556
    }
 
4557
};
 
4558
 
 
4559
exports.setDefaultValues = function(path, optionHash) {
 
4560
    Object.keys(optionHash).forEach(function(key) {
 
4561
        exports.setDefaultValue(path, key, optionHash[key]);
 
4562
    });
 
4563
};
 
4564
 
 
4565
});
 
4566
define('ace/lib/net', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
 
4567
 
 
4568
var dom = require("./dom");
 
4569
 
 
4570
exports.get = function (url, callback) {
 
4571
    var xhr = new XMLHttpRequest();
 
4572
    xhr.open('GET', url, true);
 
4573
    xhr.onreadystatechange = function () {
 
4574
        if (xhr.readyState === 4) {
 
4575
            callback(xhr.responseText);
 
4576
        }
 
4577
    };
 
4578
    xhr.send(null);
 
4579
};
 
4580
 
 
4581
exports.loadScript = function(path, callback) {
 
4582
    var head = dom.getDocumentHead();
 
4583
    var s = document.createElement('script');
 
4584
 
 
4585
    s.src = path;
 
4586
    head.appendChild(s);
 
4587
 
 
4588
    s.onload = s.onreadystatechange = function(_, isAbort) {
 
4589
        if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") {
 
4590
            s = s.onload = s.onreadystatechange = null;
 
4591
            if (!isAbort)
 
4592
                callback();
 
4593
        }
 
4594
    };
 
4595
};
 
4596
 
 
4597
});
 
4598
 
 
4599
define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
 
4600
 
 
4601
 
 
4602
var EventEmitter = {};
 
4603
var stopPropagation = function() { this.propagationStopped = true; };
 
4604
var preventDefault = function() { this.defaultPrevented = true; };
 
4605
 
 
4606
EventEmitter._emit =
 
4607
EventEmitter._dispatchEvent = function(eventName, e) {
 
4608
    this._eventRegistry || (this._eventRegistry = {});
 
4609
    this._defaultHandlers || (this._defaultHandlers = {});
 
4610
 
 
4611
    var listeners = this._eventRegistry[eventName] || [];
 
4612
    var defaultHandler = this._defaultHandlers[eventName];
 
4613
    if (!listeners.length && !defaultHandler)
 
4614
        return;
 
4615
 
 
4616
    if (typeof e != "object" || !e)
 
4617
        e = {};
 
4618
 
 
4619
    if (!e.type)
 
4620
        e.type = eventName;
 
4621
    if (!e.stopPropagation)
 
4622
        e.stopPropagation = stopPropagation;
 
4623
    if (!e.preventDefault)
 
4624
        e.preventDefault = preventDefault;
 
4625
    if (!e.target)
 
4626
        e.target = this;
 
4627
 
 
4628
    for (var i=0; i<listeners.length; i++) {
 
4629
        listeners[i](e);
 
4630
        if (e.propagationStopped)
 
4631
            break;
 
4632
    }
 
4633
    
 
4634
    if (defaultHandler && !e.defaultPrevented)
 
4635
        return defaultHandler(e);
 
4636
};
 
4637
 
 
4638
 
 
4639
EventEmitter._signal = function(eventName, e) {
 
4640
    var listeners = (this._eventRegistry || {})[eventName];
 
4641
    if (!listeners)
 
4642
        return;
 
4643
 
 
4644
    for (var i=0; i<listeners.length; i++)
 
4645
        listeners[i](e);
 
4646
};
 
4647
 
 
4648
EventEmitter.once = function(eventName, callback) {
 
4649
    var _self = this;
 
4650
    var newCallback = function() {
 
4651
        fun && fun.apply(null, arguments);
 
4652
        _self.removeEventListener(event, newCallback);
 
4653
    };
 
4654
    this.addEventListener(event, newCallback);
 
4655
};
 
4656
 
 
4657
 
 
4658
EventEmitter.setDefaultHandler = function(eventName, callback) {
 
4659
    this._defaultHandlers = this._defaultHandlers || {};
 
4660
    
 
4661
    if (this._defaultHandlers[eventName])
 
4662
        throw new Error("The default handler for '" + eventName + "' is already set");
 
4663
        
 
4664
    this._defaultHandlers[eventName] = callback;
 
4665
};
 
4666
 
 
4667
EventEmitter.on =
 
4668
EventEmitter.addEventListener = function(eventName, callback, capturing) {
 
4669
    this._eventRegistry = this._eventRegistry || {};
 
4670
 
 
4671
    var listeners = this._eventRegistry[eventName];
 
4672
    if (!listeners)
 
4673
        listeners = this._eventRegistry[eventName] = [];
 
4674
 
 
4675
    if (listeners.indexOf(callback) == -1)
 
4676
        listeners[capturing ? "unshift" : "push"](callback);
 
4677
    return callback;
 
4678
};
 
4679
 
 
4680
EventEmitter.removeListener =
 
4681
EventEmitter.removeEventListener = function(eventName, callback) {
 
4682
    this._eventRegistry = this._eventRegistry || {};
 
4683
 
 
4684
    var listeners = this._eventRegistry[eventName];
 
4685
    if (!listeners)
 
4686
        return;
 
4687
 
 
4688
    var index = listeners.indexOf(callback);
 
4689
    if (index !== -1)
 
4690
        listeners.splice(index, 1);
 
4691
};
 
4692
 
 
4693
EventEmitter.removeAllListeners = function(eventName) {
 
4694
    if (this._eventRegistry) this._eventRegistry[eventName] = [];
 
4695
};
 
4696
 
 
4697
exports.EventEmitter = EventEmitter;
 
4698
 
 
4699
});
 
4700
 
 
4701
define('ace/mouse/fold_handler', ['require', 'exports', 'module' ], function(require, exports, module) {
 
4702
 
 
4703
 
 
4704
function FoldHandler(editor) {
 
4705
 
 
4706
    editor.on("click", function(e) {
 
4707
        var position = e.getDocumentPosition();
 
4708
        var session = editor.session;
 
4709
        var fold = session.getFoldAt(position.row, position.column, 1);
 
4710
        if (fold) {
 
4711
            if (e.getAccelKey())
 
4712
                session.removeFold(fold);
 
4713
            else
 
4714
                session.expandFold(fold);
 
4715
 
 
4716
            e.stop();
 
4717
        }
 
4718
    });
 
4719
 
 
4720
    editor.on("guttermousedown", function(e) {
 
4721
        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
 
4722
 
 
4723
        if (gutterRegion == "foldWidgets") {
 
4724
            var row = e.getDocumentPosition().row;
 
4725
            var session = editor.session;
 
4726
            if (session.foldWidgets && session.foldWidgets[row])
 
4727
                editor.session.onFoldWidgetClick(row, e);
 
4728
            if (!editor.isFocused())
 
4729
                editor.focus();
 
4730
            e.stop();
 
4731
        }
 
4732
    });
 
4733
 
 
4734
    editor.on("gutterdblclick", function(e) {
 
4735
        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
 
4736
 
 
4737
        if (gutterRegion == "foldWidgets") {
 
4738
            var row = e.getDocumentPosition().row;
 
4739
            var session = editor.session;
 
4740
            var data = session.getParentFoldRangeData(row, true);
 
4741
            var range = data.range || data.firstRange;
 
4742
 
 
4743
            if (range) {
 
4744
                var row = range.start.row;
 
4745
                var fold = session.getFoldAt(row, session.getLine(row).length, 1);
 
4746
 
 
4747
                if (fold) {
 
4748
                    session.removeFold(fold);
 
4749
                } else {
 
4750
                    session.addFold("...", range);
 
4751
                    editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});
 
4752
                }
 
4753
            }
 
4754
            e.stop();
 
4755
        }
 
4756
    });
 
4757
}
 
4758
 
 
4759
exports.FoldHandler = FoldHandler;
 
4760
 
 
4761
});
 
4762
 
 
4763
define('ace/keyboard/keybinding', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/event'], function(require, exports, module) {
 
4764
 
 
4765
 
 
4766
var keyUtil  = require("../lib/keys");
 
4767
var event = require("../lib/event");
 
4768
 
 
4769
var KeyBinding = function(editor) {
 
4770
    this.$editor = editor;
 
4771
    this.$data = { };
 
4772
    this.$handlers = [];
 
4773
    this.setDefaultHandler(editor.commands);
 
4774
};
 
4775
 
 
4776
(function() {
 
4777
    this.setDefaultHandler = function(kb) {
 
4778
        this.removeKeyboardHandler(this.$defaultHandler);
 
4779
        this.$defaultHandler = kb;
 
4780
        this.addKeyboardHandler(kb, 0);
 
4781
        this.$data = {editor: this.$editor};
 
4782
    };
 
4783
 
 
4784
    this.setKeyboardHandler = function(kb) {
 
4785
        if (this.$handlers[this.$handlers.length - 1] == kb)
 
4786
            return;
 
4787
 
 
4788
        while (this.$handlers[1])
 
4789
            this.removeKeyboardHandler(this.$handlers[1]);
 
4790
 
 
4791
        this.addKeyboardHandler(kb, 1);
 
4792
    };
 
4793
 
 
4794
    this.addKeyboardHandler = function(kb, pos) {
 
4795
        if (!kb)
 
4796
            return;
 
4797
        var i = this.$handlers.indexOf(kb);
 
4798
        if (i != -1)
 
4799
            this.$handlers.splice(i, 1);
 
4800
 
 
4801
        if (pos == undefined)
 
4802
            this.$handlers.push(kb);
 
4803
        else
 
4804
            this.$handlers.splice(pos, 0, kb);
 
4805
 
 
4806
        if (i == -1 && kb.attach)
 
4807
            kb.attach(this.$editor);
 
4808
    };
 
4809
 
 
4810
    this.removeKeyboardHandler = function(kb) {
 
4811
        var i = this.$handlers.indexOf(kb);
 
4812
        if (i == -1)
 
4813
            return false;
 
4814
        this.$handlers.splice(i, 1);
 
4815
        kb.detach && kb.detach(this.$editor);
 
4816
        return true;
 
4817
    };
 
4818
 
 
4819
    this.getKeyboardHandler = function() {
 
4820
        return this.$handlers[this.$handlers.length - 1];
 
4821
    };
 
4822
 
 
4823
    this.$callKeyboardHandlers = function (hashId, keyString, keyCode, e) {
 
4824
        var toExecute;
 
4825
        var success = false;
 
4826
        var commands = this.$editor.commands;
 
4827
 
 
4828
        for (var i = this.$handlers.length; i--;) {
 
4829
            toExecute = this.$handlers[i].handleKeyboard(
 
4830
                this.$data, hashId, keyString, keyCode, e
 
4831
            );
 
4832
            if (!toExecute || !toExecute.command)
 
4833
                continue;
 
4834
            if (toExecute.command == "null") {
 
4835
                success = toExecute.passEvent != true;
 
4836
            } else {
 
4837
                success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);                
 
4838
            }
 
4839
            if (success && e && hashId != -1)
 
4840
                event.stopEvent(e);
 
4841
            if (success)
 
4842
                break;
 
4843
        }
 
4844
        return success;
 
4845
    };
 
4846
 
 
4847
    this.onCommandKey = function(e, hashId, keyCode) {
 
4848
        var keyString = keyUtil.keyCodeToString(keyCode);
 
4849
        this.$callKeyboardHandlers(hashId, keyString, keyCode, e);
 
4850
    };
 
4851
 
 
4852
    this.onTextInput = function(text) {
 
4853
        var success = this.$callKeyboardHandlers(-1, text);
 
4854
        if (!success)
 
4855
            this.$editor.commands.exec("insertstring", this.$editor, text);
 
4856
    };
 
4857
 
 
4858
}).call(KeyBinding.prototype);
 
4859
 
 
4860
exports.KeyBinding = KeyBinding;
 
4861
});
 
4862
 
 
4863
define('ace/edit_session', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', '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) {
 
4864
 
 
4865
 
 
4866
var oop = require("./lib/oop");
 
4867
var lang = require("./lib/lang");
 
4868
var config = require("./config");
 
4869
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
4870
var Selection = require("./selection").Selection;
 
4871
var TextMode = require("./mode/text").Mode;
 
4872
var Range = require("./range").Range;
 
4873
var Document = require("./document").Document;
 
4874
var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
 
4875
var SearchHighlight = require("./search_highlight").SearchHighlight;
 
4876
 
 
4877
var EditSession = function(text, mode) {
 
4878
    this.$breakpoints = [];
 
4879
    this.$decorations = [];
 
4880
    this.$frontMarkers = {};
 
4881
    this.$backMarkers = {};
 
4882
    this.$markerId = 1;
 
4883
    this.$undoSelect = true;
 
4884
 
 
4885
    this.$foldData = [];
 
4886
    this.$foldData.toString = function() {
 
4887
        return this.join("\n");
 
4888
    }
 
4889
    this.on("changeFold", this.onChangeFold.bind(this));
 
4890
    this.$onChange = this.onChange.bind(this);
 
4891
 
 
4892
    if (typeof text != "object" || !text.getLine)
 
4893
        text = new Document(text);
 
4894
 
 
4895
    this.setDocument(text);
 
4896
 
 
4897
    this.selection = new Selection(this);
 
4898
    this.setMode(mode);
 
4899
 
 
4900
    config.resetOptions(this);
 
4901
    config._emit("session", this);
 
4902
};
 
4903
 
 
4904
 
 
4905
(function() {
 
4906
 
 
4907
    oop.implement(this, EventEmitter);
 
4908
    this.setDocument = function(doc) {
 
4909
        if (this.doc)
 
4910
            this.doc.removeListener("change", this.$onChange);
 
4911
 
 
4912
        this.doc = doc;
 
4913
        doc.on("change", this.$onChange);
 
4914
 
 
4915
        if (this.bgTokenizer)
 
4916
            this.bgTokenizer.setDocument(this.getDocument());
 
4917
 
 
4918
        this.resetCaches();
 
4919
    };
 
4920
    this.getDocument = function() {
 
4921
        return this.doc;
 
4922
    };
 
4923
    this.$resetRowCache = function(docRow) {
 
4924
        if (!docRow) {
 
4925
            this.$docRowCache = [];
 
4926
            this.$screenRowCache = [];
 
4927
            return;
 
4928
        }
 
4929
        var l = this.$docRowCache.length;
 
4930
        var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;
 
4931
        if (l > i) {
 
4932
            this.$docRowCache.splice(i, l);
 
4933
            this.$screenRowCache.splice(i, l);
 
4934
        }
 
4935
    };
 
4936
 
 
4937
    this.$getRowCacheIndex = function(cacheArray, val) {
 
4938
        var low = 0;
 
4939
        var hi = cacheArray.length - 1;
 
4940
 
 
4941
        while (low <= hi) {
 
4942
            var mid = (low + hi) >> 1;
 
4943
            var c = cacheArray[mid];
 
4944
 
 
4945
            if (val > c)
 
4946
                low = mid + 1;
 
4947
            else if (val < c)
 
4948
                hi = mid - 1;
 
4949
            else
 
4950
                return mid;
 
4951
        }
 
4952
 
 
4953
        return low -1;
 
4954
    };
 
4955
 
 
4956
    this.resetCaches = function() {
 
4957
        this.$modified = true;
 
4958
        this.$wrapData = [];
 
4959
        this.$rowLengthCache = [];
 
4960
        this.$resetRowCache(0);
 
4961
        if (this.bgTokenizer)
 
4962
            this.bgTokenizer.start(0);
 
4963
    };
 
4964
 
 
4965
    this.onChangeFold = function(e) {
 
4966
        var fold = e.data;
 
4967
        this.$resetRowCache(fold.start.row);
 
4968
    };
 
4969
 
 
4970
    this.onChange = function(e) {
 
4971
        var delta = e.data;
 
4972
        this.$modified = true;
 
4973
 
 
4974
        this.$resetRowCache(delta.range.start.row);
 
4975
 
 
4976
        var removedFolds = this.$updateInternalDataOnChange(e);
 
4977
        if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
 
4978
            this.$deltasDoc.push(delta);
 
4979
            if (removedFolds && removedFolds.length != 0) {
 
4980
                this.$deltasFold.push({
 
4981
                    action: "removeFolds",
 
4982
                    folds:  removedFolds
 
4983
                });
 
4984
            }
 
4985
 
 
4986
            this.$informUndoManager.schedule();
 
4987
        }
 
4988
 
 
4989
        this.bgTokenizer.$updateOnChange(delta);
 
4990
        this._emit("change", e);
 
4991
    };
 
4992
    this.setValue = function(text) {
 
4993
        this.doc.setValue(text);
 
4994
        this.selection.moveCursorTo(0, 0);
 
4995
        this.selection.clearSelection();
 
4996
 
 
4997
        this.$resetRowCache(0);
 
4998
        this.$deltas = [];
 
4999
        this.$deltasDoc = [];
 
5000
        this.$deltasFold = [];
 
5001
        this.getUndoManager().reset();
 
5002
    };
 
5003
    this.getValue =
 
5004
    this.toString = function() {
 
5005
        return this.doc.getValue();
 
5006
    };
 
5007
    this.getSelection = function() {
 
5008
        return this.selection;
 
5009
    };
 
5010
    this.getState = function(row) {
 
5011
        return this.bgTokenizer.getState(row);
 
5012
    };
 
5013
    this.getTokens = function(row) {
 
5014
        return this.bgTokenizer.getTokens(row);
 
5015
    };
 
5016
    this.getTokenAt = function(row, column) {
 
5017
        var tokens = this.bgTokenizer.getTokens(row);
 
5018
        var token, c = 0;
 
5019
        if (column == null) {
 
5020
            i = tokens.length - 1;
 
5021
            c = this.getLine(row).length;
 
5022
        } else {
 
5023
            for (var i = 0; i < tokens.length; i++) {
 
5024
                c += tokens[i].value.length;
 
5025
                if (c >= column)
 
5026
                    break;
 
5027
            }
 
5028
        }
 
5029
        token = tokens[i];
 
5030
        if (!token)
 
5031
            return null;
 
5032
        token.index = i;
 
5033
        token.start = c - token.value.length;
 
5034
        return token;
 
5035
    };
 
5036
    this.setUndoManager = function(undoManager) {
 
5037
        this.$undoManager = undoManager;
 
5038
        this.$deltas = [];
 
5039
        this.$deltasDoc = [];
 
5040
        this.$deltasFold = [];
 
5041
 
 
5042
        if (this.$informUndoManager)
 
5043
            this.$informUndoManager.cancel();
 
5044
 
 
5045
        if (undoManager) {
 
5046
            var self = this;
 
5047
 
 
5048
            this.$syncInformUndoManager = function() {
 
5049
                self.$informUndoManager.cancel();
 
5050
 
 
5051
                if (self.$deltasFold.length) {
 
5052
                    self.$deltas.push({
 
5053
                        group: "fold",
 
5054
                        deltas: self.$deltasFold
 
5055
                    });
 
5056
                    self.$deltasFold = [];
 
5057
                }
 
5058
 
 
5059
                if (self.$deltasDoc.length) {
 
5060
                    self.$deltas.push({
 
5061
                        group: "doc",
 
5062
                        deltas: self.$deltasDoc
 
5063
                    });
 
5064
                    self.$deltasDoc = [];
 
5065
                }
 
5066
 
 
5067
                if (self.$deltas.length > 0) {
 
5068
                    undoManager.execute({
 
5069
                        action: "aceupdate",
 
5070
                        args: [self.$deltas, self]
 
5071
                    });
 
5072
                }
 
5073
 
 
5074
                self.$deltas = [];
 
5075
            }
 
5076
            this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);
 
5077
        }
 
5078
    };
 
5079
 
 
5080
    this.$defaultUndoManager = {
 
5081
        undo: function() {},
 
5082
        redo: function() {},
 
5083
        reset: function() {}
 
5084
    };
 
5085
    this.getUndoManager = function() {
 
5086
        return this.$undoManager || this.$defaultUndoManager;
 
5087
    };
 
5088
    this.getTabString = function() {
 
5089
        if (this.getUseSoftTabs()) {
 
5090
            return lang.stringRepeat(" ", this.getTabSize());
 
5091
        } else {
 
5092
            return "\t";
 
5093
        }
 
5094
    };
 
5095
    this.setUseSoftTabs = function(val) {
 
5096
        this.setOption("useSoftTabs", val);
 
5097
    };
 
5098
    this.getUseSoftTabs = function() {
 
5099
         return this.$useSoftTabs;
 
5100
    };
 
5101
    this.setTabSize = function(tabSize) {
 
5102
        this.setOption("tabSize", tabSize)
 
5103
    };
 
5104
    this.getTabSize = function() {
 
5105
        return this.$tabSize;
 
5106
    };
 
5107
    this.isTabStop = function(position) {
 
5108
        return this.$useSoftTabs && (position.column % this.$tabSize == 0);
 
5109
    };
 
5110
 
 
5111
    this.$overwrite = false;
 
5112
    this.setOverwrite = function(overwrite) {
 
5113
        if (this.$overwrite == overwrite) return;
 
5114
 
 
5115
        this.$overwrite = overwrite;
 
5116
        this._emit("changeOverwrite");
 
5117
    };
 
5118
    this.getOverwrite = function() {
 
5119
        return this.$overwrite;
 
5120
    };
 
5121
    this.toggleOverwrite = function() {
 
5122
        this.setOverwrite(!this.$overwrite);
 
5123
    };
 
5124
    this.addGutterDecoration = function(row, className) {
 
5125
        if (!this.$decorations[row])
 
5126
            this.$decorations[row] = "";
 
5127
        this.$decorations[row] += " " + className;
 
5128
        this._emit("changeBreakpoint", {});
 
5129
    };
 
5130
    this.removeGutterDecoration = function(row, className) {
 
5131
        this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
 
5132
        this._emit("changeBreakpoint", {});
 
5133
    };
 
5134
    this.getBreakpoints = function() {
 
5135
        return this.$breakpoints;
 
5136
    };
 
5137
    this.setBreakpoints = function(rows) {
 
5138
        this.$breakpoints = [];
 
5139
        for (var i=0; i<rows.length; i++) {
 
5140
            this.$breakpoints[rows[i]] = "ace_breakpoint";
 
5141
        }
 
5142
        this._emit("changeBreakpoint", {});
 
5143
    };
 
5144
    this.clearBreakpoints = function() {
 
5145
        this.$breakpoints = [];
 
5146
        this._emit("changeBreakpoint", {});
 
5147
    };
 
5148
    this.setBreakpoint = function(row, className) {
 
5149
        if (className === undefined)
 
5150
            className = "ace_breakpoint";
 
5151
        if (className)
 
5152
            this.$breakpoints[row] = className;
 
5153
        else
 
5154
            delete this.$breakpoints[row];
 
5155
        this._emit("changeBreakpoint", {});
 
5156
    };
 
5157
    this.clearBreakpoint = function(row) {
 
5158
        delete this.$breakpoints[row];
 
5159
        this._emit("changeBreakpoint", {});
 
5160
    };
 
5161
    this.addMarker = function(range, clazz, type, inFront) {
 
5162
        var id = this.$markerId++;
 
5163
 
 
5164
        var marker = {
 
5165
            range : range,
 
5166
            type : type || "line",
 
5167
            renderer: typeof type == "function" ? type : null,
 
5168
            clazz : clazz,
 
5169
            inFront: !!inFront,
 
5170
            id: id
 
5171
        }
 
5172
 
 
5173
        if (inFront) {
 
5174
            this.$frontMarkers[id] = marker;
 
5175
            this._emit("changeFrontMarker")
 
5176
        } else {
 
5177
            this.$backMarkers[id] = marker;
 
5178
            this._emit("changeBackMarker")
 
5179
        }
 
5180
 
 
5181
        return id;
 
5182
    };
 
5183
    this.addDynamicMarker = function(marker, inFront) {
 
5184
        if (!marker.update)
 
5185
            return;
 
5186
        var id = this.$markerId++;
 
5187
        marker.id = id;
 
5188
        marker.inFront = !!inFront;
 
5189
 
 
5190
        if (inFront) {
 
5191
            this.$frontMarkers[id] = marker;
 
5192
            this._emit("changeFrontMarker")
 
5193
        } else {
 
5194
            this.$backMarkers[id] = marker;
 
5195
            this._emit("changeBackMarker")
 
5196
        }
 
5197
 
 
5198
        return marker;
 
5199
    };
 
5200
    this.removeMarker = function(markerId) {
 
5201
        var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
 
5202
        if (!marker)
 
5203
            return;
 
5204
 
 
5205
        var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
 
5206
        if (marker) {
 
5207
            delete (markers[markerId]);
 
5208
            this._emit(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
 
5209
        }
 
5210
    };
 
5211
    this.getMarkers = function(inFront) {
 
5212
        return inFront ? this.$frontMarkers : this.$backMarkers;
 
5213
    };
 
5214
 
 
5215
    this.highlight = function(re) {
 
5216
        if (!this.$searchHighlight) {
 
5217
            var highlight = new SearchHighlight(null, "ace_selected-word", "text");
 
5218
            this.$searchHighlight = this.addDynamicMarker(highlight);
 
5219
        }
 
5220
        this.$searchHighlight.setRegexp(re);
 
5221
    }
 
5222
    this.highlightLines = function(startRow, endRow, clazz, inFront) {
 
5223
        if (typeof endRow != "number") {
 
5224
            clazz = endRow;
 
5225
            endRow = startRow;
 
5226
        }
 
5227
        if (!clazz)
 
5228
            clazz = "ace_step";
 
5229
 
 
5230
        var range = new Range(startRow, 0, endRow, Infinity);
 
5231
        range.id = this.addMarker(range, clazz, "fullLine", inFront);
 
5232
        return range;
 
5233
    };
 
5234
    this.setAnnotations = function(annotations) {
 
5235
        this.$annotations = annotations;
 
5236
        this._emit("changeAnnotation", {});
 
5237
    };
 
5238
    this.getAnnotations = function() {
 
5239
        return this.$annotations || [];
 
5240
    };
 
5241
    this.clearAnnotations = function() {
 
5242
        this.setAnnotations([]);
 
5243
    };
 
5244
    this.$detectNewLine = function(text) {
 
5245
        var match = text.match(/^.*?(\r?\n)/m);
 
5246
        if (match) {
 
5247
            this.$autoNewLine = match[1];
 
5248
        } else {
 
5249
            this.$autoNewLine = "\n";
 
5250
        }
 
5251
    };
 
5252
    this.getWordRange = function(row, column) {
 
5253
        var line = this.getLine(row);
 
5254
 
 
5255
        var inToken = false;
 
5256
        if (column > 0)
 
5257
            inToken = !!line.charAt(column - 1).match(this.tokenRe);
 
5258
 
 
5259
        if (!inToken)
 
5260
            inToken = !!line.charAt(column).match(this.tokenRe);
 
5261
 
 
5262
        if (inToken)
 
5263
            var re = this.tokenRe;
 
5264
        else if (/^\s+$/.test(line.slice(column-1, column+1)))
 
5265
            var re = /\s/;
 
5266
        else
 
5267
            var re = this.nonTokenRe;
 
5268
 
 
5269
        var start = column;
 
5270
        if (start > 0) {
 
5271
            do {
 
5272
                start--;
 
5273
            }
 
5274
            while (start >= 0 && line.charAt(start).match(re));
 
5275
            start++;
 
5276
        }
 
5277
 
 
5278
        var end = column;
 
5279
        while (end < line.length && line.charAt(end).match(re)) {
 
5280
            end++;
 
5281
        }
 
5282
 
 
5283
        return new Range(row, start, row, end);
 
5284
    };
 
5285
    this.getAWordRange = function(row, column) {
 
5286
        var wordRange = this.getWordRange(row, column);
 
5287
        var line = this.getLine(wordRange.end.row);
 
5288
 
 
5289
        while (line.charAt(wordRange.end.column).match(/[ \t]/)) {
 
5290
            wordRange.end.column += 1;
 
5291
        }
 
5292
        return wordRange;
 
5293
    };
 
5294
    this.setNewLineMode = function(newLineMode) {
 
5295
        this.doc.setNewLineMode(newLineMode);
 
5296
    };
 
5297
    this.getNewLineMode = function() {
 
5298
        return this.doc.getNewLineMode();
 
5299
    };
 
5300
    this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); };
 
5301
    this.getUseWorker = function() { return this.$useWorker; };
 
5302
    this.onReloadTokenizer = function(e) {
 
5303
        var rows = e.data;
 
5304
        this.bgTokenizer.start(rows.first);
 
5305
        this._emit("tokenizerUpdate", e);
 
5306
    };
 
5307
 
 
5308
    this.$modes = {};
 
5309
    this.$mode = null;
 
5310
    this.$modeId = null;
 
5311
    this.setMode = function(mode) {
 
5312
        if (mode && typeof mode === "object") {
 
5313
            if (mode.getTokenizer)
 
5314
                return this.$onChangeMode(mode);
 
5315
            var options = mode;
 
5316
            var path = options.path;
 
5317
        } else {
 
5318
            path = mode || "ace/mode/text";
 
5319
        }
 
5320
        if (!this.$modes["ace/mode/text"])
 
5321
            this.$modes["ace/mode/text"] = new TextMode();
 
5322
 
 
5323
        if (this.$modes[path] && !options)
 
5324
            return this.$onChangeMode(this.$modes[path]);
 
5325
        this.$modeId = path;
 
5326
        config.loadModule(["mode", path], function(m) {
 
5327
            if (this.$modeId !== path)
 
5328
                return;
 
5329
            if (this.$modes[path] && !options)
 
5330
                return this.$onChangeMode(this.$modes[path]);
 
5331
            if (m && m.Mode) {
 
5332
                m = new m.Mode(options);
 
5333
                if (!options) {
 
5334
                    this.$modes[path] = m;
 
5335
                    m.$id = path;
 
5336
                }
 
5337
                this.$onChangeMode(m)
 
5338
            }
 
5339
        }.bind(this));
 
5340
        if (!this.$mode)
 
5341
            this.$onChangeMode(this.$modes["ace/mode/text"], true);
 
5342
    };
 
5343
 
 
5344
    this.$onChangeMode = function(mode, $isPlaceholder) {
 
5345
        if (this.$mode === mode) return;
 
5346
        this.$mode = mode;
 
5347
 
 
5348
        this.$stopWorker();
 
5349
 
 
5350
        if (this.$useWorker)
 
5351
            this.$startWorker();
 
5352
 
 
5353
        var tokenizer = mode.getTokenizer();
 
5354
 
 
5355
        if(tokenizer.addEventListener !== undefined) {
 
5356
            var onReloadTokenizer = this.onReloadTokenizer.bind(this);
 
5357
            tokenizer.addEventListener("update", onReloadTokenizer);
 
5358
        }
 
5359
 
 
5360
        if (!this.bgTokenizer) {
 
5361
            this.bgTokenizer = new BackgroundTokenizer(tokenizer);
 
5362
            var _self = this;
 
5363
            this.bgTokenizer.addEventListener("update", function(e) {
 
5364
                _self._emit("tokenizerUpdate", e);
 
5365
            });
 
5366
        } else {
 
5367
            this.bgTokenizer.setTokenizer(tokenizer);
 
5368
        }
 
5369
 
 
5370
        this.bgTokenizer.setDocument(this.getDocument());
 
5371
 
 
5372
        this.tokenRe = mode.tokenRe;
 
5373
        this.nonTokenRe = mode.nonTokenRe;
 
5374
 
 
5375
 
 
5376
        if (!$isPlaceholder) {
 
5377
            this.$modeId = mode.$id;
 
5378
            this.$setFolding(mode.foldingRules);
 
5379
            this._emit("changeMode");
 
5380
            this.bgTokenizer.start(0);
 
5381
        }
 
5382
    };
 
5383
 
 
5384
 
 
5385
    this.$stopWorker = function() {
 
5386
        if (this.$worker)
 
5387
            this.$worker.terminate();
 
5388
 
 
5389
        this.$worker = null;
 
5390
    };
 
5391
 
 
5392
    this.$startWorker = function() {
 
5393
        if (typeof Worker !== "undefined" && !require.noWorker) {
 
5394
            try {
 
5395
                this.$worker = this.$mode.createWorker(this);
 
5396
            } catch (e) {
 
5397
                console.log("Could not load worker");
 
5398
                console.log(e);
 
5399
                this.$worker = null;
 
5400
            }
 
5401
        }
 
5402
        else
 
5403
            this.$worker = null;
 
5404
    };
 
5405
    this.getMode = function() {
 
5406
        return this.$mode;
 
5407
    };
 
5408
 
 
5409
    this.$scrollTop = 0;
 
5410
    this.setScrollTop = function(scrollTop) {
 
5411
        scrollTop = Math.round(Math.max(0, scrollTop));
 
5412
        if (this.$scrollTop === scrollTop || isNaN(scrollTop))
 
5413
            return;
 
5414
 
 
5415
        this.$scrollTop = scrollTop;
 
5416
        this._signal("changeScrollTop", scrollTop);
 
5417
    };
 
5418
    this.getScrollTop = function() {
 
5419
        return this.$scrollTop;
 
5420
    };
 
5421
 
 
5422
    this.$scrollLeft = 0;
 
5423
    this.setScrollLeft = function(scrollLeft) {
 
5424
        scrollLeft = Math.round(Math.max(0, scrollLeft));
 
5425
        if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
 
5426
            return;
 
5427
 
 
5428
        this.$scrollLeft = scrollLeft;
 
5429
        this._signal("changeScrollLeft", scrollLeft);
 
5430
    };
 
5431
    this.getScrollLeft = function() {
 
5432
        return this.$scrollLeft;
 
5433
    };
 
5434
    this.getScreenWidth = function() {
 
5435
        this.$computeWidth();
 
5436
        return this.screenWidth;
 
5437
    };
 
5438
 
 
5439
    this.$computeWidth = function(force) {
 
5440
        if (this.$modified || force) {
 
5441
            this.$modified = false;
 
5442
 
 
5443
            if (this.$useWrapMode)
 
5444
                return this.screenWidth = this.$wrapLimit;
 
5445
 
 
5446
            var lines = this.doc.getAllLines();
 
5447
            var cache = this.$rowLengthCache;
 
5448
            var longestScreenLine = 0;
 
5449
            var foldIndex = 0;
 
5450
            var foldLine = this.$foldData[foldIndex];
 
5451
            var foldStart = foldLine ? foldLine.start.row : Infinity;
 
5452
            var len = lines.length;
 
5453
 
 
5454
            for (var i = 0; i < len; i++) {
 
5455
                if (i > foldStart) {
 
5456
                    i = foldLine.end.row + 1;
 
5457
                    if (i >= len)
 
5458
                        break;
 
5459
                    foldLine = this.$foldData[foldIndex++];
 
5460
                    foldStart = foldLine ? foldLine.start.row : Infinity;
 
5461
                }
 
5462
 
 
5463
                if (cache[i] == null)
 
5464
                    cache[i] = this.$getStringScreenWidth(lines[i])[0];
 
5465
 
 
5466
                if (cache[i] > longestScreenLine)
 
5467
                    longestScreenLine = cache[i];
 
5468
            }
 
5469
            this.screenWidth = longestScreenLine;
 
5470
        }
 
5471
    };
 
5472
    this.getLine = function(row) {
 
5473
        return this.doc.getLine(row);
 
5474
    };
 
5475
    this.getLines = function(firstRow, lastRow) {
 
5476
        return this.doc.getLines(firstRow, lastRow);
 
5477
    };
 
5478
    this.getLength = function() {
 
5479
        return this.doc.getLength();
 
5480
    };
 
5481
    this.getTextRange = function(range) {
 
5482
        return this.doc.getTextRange(range || this.selection.getRange());
 
5483
    };
 
5484
    this.insert = function(position, text) {
 
5485
        return this.doc.insert(position, text);
 
5486
    };
 
5487
    this.remove = function(range) {
 
5488
        return this.doc.remove(range);
 
5489
    };
 
5490
    this.undoChanges = function(deltas, dontSelect) {
 
5491
        if (!deltas.length)
 
5492
            return;
 
5493
 
 
5494
        this.$fromUndo = true;
 
5495
        var lastUndoRange = null;
 
5496
        for (var i = deltas.length - 1; i != -1; i--) {
 
5497
            var delta = deltas[i];
 
5498
            if (delta.group == "doc") {
 
5499
                this.doc.revertDeltas(delta.deltas);
 
5500
                lastUndoRange =
 
5501
                    this.$getUndoSelection(delta.deltas, true, lastUndoRange);
 
5502
            } else {
 
5503
                delta.deltas.forEach(function(foldDelta) {
 
5504
                    this.addFolds(foldDelta.folds);
 
5505
                }, this);
 
5506
            }
 
5507
        }
 
5508
        this.$fromUndo = false;
 
5509
        lastUndoRange &&
 
5510
            this.$undoSelect &&
 
5511
            !dontSelect &&
 
5512
            this.selection.setSelectionRange(lastUndoRange);
 
5513
        return lastUndoRange;
 
5514
    };
 
5515
    this.redoChanges = function(deltas, dontSelect) {
 
5516
        if (!deltas.length)
 
5517
            return;
 
5518
 
 
5519
        this.$fromUndo = true;
 
5520
        var lastUndoRange = null;
 
5521
        for (var i = 0; i < deltas.length; i++) {
 
5522
            var delta = deltas[i];
 
5523
            if (delta.group == "doc") {
 
5524
                this.doc.applyDeltas(delta.deltas);
 
5525
                lastUndoRange =
 
5526
                    this.$getUndoSelection(delta.deltas, false, lastUndoRange);
 
5527
            }
 
5528
        }
 
5529
        this.$fromUndo = false;
 
5530
        lastUndoRange &&
 
5531
            this.$undoSelect &&
 
5532
            !dontSelect &&
 
5533
            this.selection.setSelectionRange(lastUndoRange);
 
5534
        return lastUndoRange;
 
5535
    };
 
5536
    this.setUndoSelect = function(enable) {
 
5537
        this.$undoSelect = enable;
 
5538
    };
 
5539
 
 
5540
    this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
 
5541
        function isInsert(delta) {
 
5542
            var insert =
 
5543
                delta.action === "insertText" || delta.action === "insertLines";
 
5544
            return isUndo ? !insert : insert;
 
5545
        }
 
5546
 
 
5547
        var delta = deltas[0];
 
5548
        var range, point;
 
5549
        var lastDeltaIsInsert = false;
 
5550
        if (isInsert(delta)) {
 
5551
            range = delta.range.clone();
 
5552
            lastDeltaIsInsert = true;
 
5553
        } else {
 
5554
            range = Range.fromPoints(delta.range.start, delta.range.start);
 
5555
            lastDeltaIsInsert = false;
 
5556
        }
 
5557
 
 
5558
        for (var i = 1; i < deltas.length; i++) {
 
5559
            delta = deltas[i];
 
5560
            if (isInsert(delta)) {
 
5561
                point = delta.range.start;
 
5562
                if (range.compare(point.row, point.column) == -1) {
 
5563
                    range.setStart(delta.range.start);
 
5564
                }
 
5565
                point = delta.range.end;
 
5566
                if (range.compare(point.row, point.column) == 1) {
 
5567
                    range.setEnd(delta.range.end);
 
5568
                }
 
5569
                lastDeltaIsInsert = true;
 
5570
            } else {
 
5571
                point = delta.range.start;
 
5572
                if (range.compare(point.row, point.column) == -1) {
 
5573
                    range =
 
5574
                        Range.fromPoints(delta.range.start, delta.range.start);
 
5575
                }
 
5576
                lastDeltaIsInsert = false;
 
5577
            }
 
5578
        }
 
5579
        if (lastUndoRange != null) {
 
5580
            var cmp = lastUndoRange.compareRange(range);
 
5581
            if (cmp == 1) {
 
5582
                range.setStart(lastUndoRange.start);
 
5583
            } else if (cmp == -1) {
 
5584
                range.setEnd(lastUndoRange.end);
 
5585
            }
 
5586
        }
 
5587
 
 
5588
        return range;
 
5589
    };
 
5590
    this.replace = function(range, text) {
 
5591
        return this.doc.replace(range, text);
 
5592
    };
 
5593
    this.moveText = function(fromRange, toPosition, copy) {
 
5594
        var text = this.getTextRange(fromRange);
 
5595
        var folds = this.getFoldsInRange(fromRange);
 
5596
 
 
5597
        var toRange = Range.fromPoints(toPosition, toPosition);
 
5598
        if (!copy) {
 
5599
            this.remove(fromRange);
 
5600
            var rowDiff = fromRange.start.row - fromRange.end.row;
 
5601
            var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;
 
5602
            if (collDiff) {
 
5603
                if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)
 
5604
                    toRange.start.column += collDiff;
 
5605
                if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)
 
5606
                    toRange.end.column += collDiff;
 
5607
            }
 
5608
            if (rowDiff && toRange.start.row >= fromRange.end.row) {
 
5609
                toRange.start.row += rowDiff;
 
5610
                toRange.end.row += rowDiff;
 
5611
            }
 
5612
        }
 
5613
 
 
5614
        this.insert(toRange.start, text);
 
5615
        if (folds.length) {
 
5616
            var oldStart = fromRange.start;
 
5617
            var newStart = toRange.start;
 
5618
            var rowDiff = newStart.row - oldStart.row;
 
5619
            var collDiff = newStart.column - oldStart.column;
 
5620
            this.addFolds(folds.map(function(x) {
 
5621
                x = x.clone();
 
5622
                if (x.start.row == oldStart.row)
 
5623
                    x.start.column += collDiff;
 
5624
                if (x.end.row == oldStart.row)
 
5625
                    x.end.column += collDiff;
 
5626
                x.start.row += rowDiff;
 
5627
                x.end.row += rowDiff;
 
5628
                return x;
 
5629
            }));
 
5630
        }
 
5631
 
 
5632
        return toRange;
 
5633
    };
 
5634
    this.indentRows = function(startRow, endRow, indentString) {
 
5635
        indentString = indentString.replace(/\t/g, this.getTabString());
 
5636
        for (var row=startRow; row<=endRow; row++)
 
5637
            this.insert({row: row, column:0}, indentString);
 
5638
    };
 
5639
    this.outdentRows = function (range) {
 
5640
        var rowRange = range.collapseRows();
 
5641
        var deleteRange = new Range(0, 0, 0, 0);
 
5642
        var size = this.getTabSize();
 
5643
 
 
5644
        for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
 
5645
            var line = this.getLine(i);
 
5646
 
 
5647
            deleteRange.start.row = i;
 
5648
            deleteRange.end.row = i;
 
5649
            for (var j = 0; j < size; ++j)
 
5650
                if (line.charAt(j) != ' ')
 
5651
                    break;
 
5652
            if (j < size && line.charAt(j) == '\t') {
 
5653
                deleteRange.start.column = j;
 
5654
                deleteRange.end.column = j + 1;
 
5655
            } else {
 
5656
                deleteRange.start.column = 0;
 
5657
                deleteRange.end.column = j;
 
5658
            }
 
5659
            this.remove(deleteRange);
 
5660
        }
 
5661
    };
 
5662
 
 
5663
    this.$moveLines = function(firstRow, lastRow, dir) {
 
5664
        firstRow = this.getRowFoldStart(firstRow);
 
5665
        lastRow = this.getRowFoldEnd(lastRow);
 
5666
        if (dir < 0) {
 
5667
            var row = this.getRowFoldStart(firstRow + dir);
 
5668
            if (row < 0) return 0;
 
5669
            var diff = row-firstRow;
 
5670
        } else if (dir > 0) {
 
5671
            var row = this.getRowFoldEnd(lastRow + dir);
 
5672
            if (row > this.doc.getLength()-1) return 0;
 
5673
            var diff = row-lastRow;
 
5674
        } else {
 
5675
            firstRow = this.$clipRowToDocument(firstRow);
 
5676
            lastRow = this.$clipRowToDocument(lastRow);
 
5677
            var diff = lastRow - firstRow + 1;
 
5678
        }
 
5679
 
 
5680
        var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);
 
5681
        var folds = this.getFoldsInRange(range).map(function(x){
 
5682
            x = x.clone();
 
5683
            x.start.row += diff;
 
5684
            x.end.row += diff;
 
5685
            return x;
 
5686
        });
 
5687
 
 
5688
        var lines = dir == 0
 
5689
            ? this.doc.getLines(firstRow, lastRow)
 
5690
            : this.doc.removeLines(firstRow, lastRow);
 
5691
        this.doc.insertLines(firstRow+diff, lines);
 
5692
        folds.length && this.addFolds(folds);
 
5693
        return diff;
 
5694
    };
 
5695
    this.moveLinesUp = function(firstRow, lastRow) {
 
5696
        return this.$moveLines(firstRow, lastRow, -1);
 
5697
    };
 
5698
    this.moveLinesDown = function(firstRow, lastRow) {
 
5699
        return this.$moveLines(firstRow, lastRow, 1);
 
5700
    };
 
5701
    this.duplicateLines = function(firstRow, lastRow) {
 
5702
        return this.$moveLines(firstRow, lastRow, 0);
 
5703
    };
 
5704
 
 
5705
 
 
5706
    this.$clipRowToDocument = function(row) {
 
5707
        return Math.max(0, Math.min(row, this.doc.getLength()-1));
 
5708
    };
 
5709
 
 
5710
    this.$clipColumnToRow = function(row, column) {
 
5711
        if (column < 0)
 
5712
            return 0;
 
5713
        return Math.min(this.doc.getLine(row).length, column);
 
5714
    };
 
5715
 
 
5716
 
 
5717
    this.$clipPositionToDocument = function(row, column) {
 
5718
        column = Math.max(0, column);
 
5719
 
 
5720
        if (row < 0) {
 
5721
            row = 0;
 
5722
            column = 0;
 
5723
        } else {
 
5724
            var len = this.doc.getLength();
 
5725
            if (row >= len) {
 
5726
                row = len - 1;
 
5727
                column = this.doc.getLine(len-1).length;
 
5728
            } else {
 
5729
                column = Math.min(this.doc.getLine(row).length, column);
 
5730
            }
 
5731
        }
 
5732
 
 
5733
        return {
 
5734
            row: row,
 
5735
            column: column
 
5736
        };
 
5737
    };
 
5738
 
 
5739
    this.$clipRangeToDocument = function(range) {
 
5740
        if (range.start.row < 0) {
 
5741
            range.start.row = 0;
 
5742
            range.start.column = 0;
 
5743
        } else {
 
5744
            range.start.column = this.$clipColumnToRow(
 
5745
                range.start.row,
 
5746
                range.start.column
 
5747
            );
 
5748
        }
 
5749
 
 
5750
        var len = this.doc.getLength() - 1;
 
5751
        if (range.end.row > len) {
 
5752
            range.end.row = len;
 
5753
            range.end.column = this.doc.getLine(len).length;
 
5754
        } else {
 
5755
            range.end.column = this.$clipColumnToRow(
 
5756
                range.end.row,
 
5757
                range.end.column
 
5758
            );
 
5759
        }
 
5760
        return range;
 
5761
    };
 
5762
    this.$wrapLimit = 80;
 
5763
    this.$useWrapMode = false;
 
5764
    this.$wrapLimitRange = {
 
5765
        min : null,
 
5766
        max : null
 
5767
    };
 
5768
    this.setUseWrapMode = function(useWrapMode) {
 
5769
        if (useWrapMode != this.$useWrapMode) {
 
5770
            this.$useWrapMode = useWrapMode;
 
5771
            this.$modified = true;
 
5772
            this.$resetRowCache(0);
 
5773
            if (useWrapMode) {
 
5774
                var len = this.getLength();
 
5775
                this.$wrapData = [];
 
5776
                for (var i = 0; i < len; i++) {
 
5777
                    this.$wrapData.push([]);
 
5778
                }
 
5779
                this.$updateWrapData(0, len - 1);
 
5780
            }
 
5781
 
 
5782
            this._emit("changeWrapMode");
 
5783
        }
 
5784
    };
 
5785
    this.getUseWrapMode = function() {
 
5786
        return this.$useWrapMode;
 
5787
    };
 
5788
    this.setWrapLimitRange = function(min, max) {
 
5789
        if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
 
5790
            this.$wrapLimitRange.min = min;
 
5791
            this.$wrapLimitRange.max = max;
 
5792
            this.$modified = true;
 
5793
            this._emit("changeWrapMode");
 
5794
        }
 
5795
    };
 
5796
    this.adjustWrapLimit = function(desiredLimit) {
 
5797
        var wrapLimit = this.$constrainWrapLimit(desiredLimit);
 
5798
        if (wrapLimit != this.$wrapLimit && wrapLimit > 0) {
 
5799
            this.$wrapLimit = wrapLimit;
 
5800
            this.$modified = true;
 
5801
            if (this.$useWrapMode) {
 
5802
                this.$updateWrapData(0, this.getLength() - 1);
 
5803
                this.$resetRowCache(0);
 
5804
                this._emit("changeWrapLimit");
 
5805
            }
 
5806
            return true;
 
5807
        }
 
5808
        return false;
 
5809
    };
 
5810
 
 
5811
    this.$constrainWrapLimit = function(wrapLimit) {
 
5812
        var min = this.$wrapLimitRange.min;
 
5813
        if (min)
 
5814
            wrapLimit = Math.max(min, wrapLimit);
 
5815
 
 
5816
        var max = this.$wrapLimitRange.max;
 
5817
        if (max)
 
5818
            wrapLimit = Math.min(max, wrapLimit);
 
5819
        return Math.max(1, wrapLimit);
 
5820
    };
 
5821
    this.getWrapLimit = function() {
 
5822
        return this.$wrapLimit;
 
5823
    };
 
5824
    this.getWrapLimitRange = function() {
 
5825
        return {
 
5826
            min : this.$wrapLimitRange.min,
 
5827
            max : this.$wrapLimitRange.max
 
5828
        };
 
5829
    };
 
5830
 
 
5831
    this.$updateInternalDataOnChange = function(e) {
 
5832
        var useWrapMode = this.$useWrapMode;
 
5833
        var len;
 
5834
        var action = e.data.action;
 
5835
        var firstRow = e.data.range.start.row;
 
5836
        var lastRow = e.data.range.end.row;
 
5837
        var start = e.data.range.start;
 
5838
        var end = e.data.range.end;
 
5839
        var removedFolds = null;
 
5840
 
 
5841
        if (action.indexOf("Lines") != -1) {
 
5842
            if (action == "insertLines") {
 
5843
                lastRow = firstRow + (e.data.lines.length);
 
5844
            } else {
 
5845
                lastRow = firstRow;
 
5846
            }
 
5847
            len = e.data.lines ? e.data.lines.length : lastRow - firstRow;
 
5848
        } else {
 
5849
            len = lastRow - firstRow;
 
5850
        }
 
5851
 
 
5852
        if (len != 0) {
 
5853
            if (action.indexOf("remove") != -1) {
 
5854
                this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len);
 
5855
 
 
5856
                var foldLines = this.$foldData;
 
5857
                removedFolds = this.getFoldsInRange(e.data.range);
 
5858
                this.removeFolds(removedFolds);
 
5859
 
 
5860
                var foldLine = this.getFoldLine(end.row);
 
5861
                var idx = 0;
 
5862
                if (foldLine) {
 
5863
                    foldLine.addRemoveChars(end.row, end.column, start.column - end.column);
 
5864
                    foldLine.shiftRow(-len);
 
5865
 
 
5866
                    var foldLineBefore = this.getFoldLine(firstRow);
 
5867
                    if (foldLineBefore && foldLineBefore !== foldLine) {
 
5868
                        foldLineBefore.merge(foldLine);
 
5869
                        foldLine = foldLineBefore;
 
5870
                    }
 
5871
                    idx = foldLines.indexOf(foldLine) + 1;
 
5872
                }
 
5873
 
 
5874
                for (idx; idx < foldLines.length; idx++) {
 
5875
                    var foldLine = foldLines[idx];
 
5876
                    if (foldLine.start.row >= end.row) {
 
5877
                        foldLine.shiftRow(-len);
 
5878
                    }
 
5879
                }
 
5880
 
 
5881
                lastRow = firstRow;
 
5882
            } else {
 
5883
                var args;
 
5884
                if (useWrapMode) {
 
5885
                    args = [firstRow, 0];
 
5886
                    for (var i = 0; i < len; i++) args.push([]);
 
5887
                    this.$wrapData.splice.apply(this.$wrapData, args);
 
5888
                } else {
 
5889
                    args = Array(len);
 
5890
                    args.unshift(firstRow, 0);
 
5891
                    this.$rowLengthCache.splice.apply(this.$rowLengthCache, args);
 
5892
                }
 
5893
                var foldLines = this.$foldData;
 
5894
                var foldLine = this.getFoldLine(firstRow);
 
5895
                var idx = 0;
 
5896
                if (foldLine) {
 
5897
                    var cmp = foldLine.range.compareInside(start.row, start.column)
 
5898
                    if (cmp == 0) {
 
5899
                        foldLine = foldLine.split(start.row, start.column);
 
5900
                        foldLine.shiftRow(len);
 
5901
                        foldLine.addRemoveChars(
 
5902
                            lastRow, 0, end.column - start.column);
 
5903
                    } else
 
5904
                    if (cmp == -1) {
 
5905
                        foldLine.addRemoveChars(firstRow, 0, end.column - start.column);
 
5906
                        foldLine.shiftRow(len);
 
5907
                    }
 
5908
                    idx = foldLines.indexOf(foldLine) + 1;
 
5909
                }
 
5910
 
 
5911
                for (idx; idx < foldLines.length; idx++) {
 
5912
                    var foldLine = foldLines[idx];
 
5913
                    if (foldLine.start.row >= firstRow) {
 
5914
                        foldLine.shiftRow(len);
 
5915
                    }
 
5916
                }
 
5917
            }
 
5918
        } else {
 
5919
            len = Math.abs(e.data.range.start.column - e.data.range.end.column);
 
5920
            if (action.indexOf("remove") != -1) {
 
5921
                removedFolds = this.getFoldsInRange(e.data.range);
 
5922
                this.removeFolds(removedFolds);
 
5923
 
 
5924
                len = -len;
 
5925
            }
 
5926
            var foldLine = this.getFoldLine(firstRow);
 
5927
            if (foldLine) {
 
5928
                foldLine.addRemoveChars(firstRow, start.column, len);
 
5929
            }
 
5930
        }
 
5931
 
 
5932
        if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {
 
5933
            console.error("doc.getLength() and $wrapData.length have to be the same!");
 
5934
        }
 
5935
 
 
5936
        if (useWrapMode)
 
5937
            this.$updateWrapData(firstRow, lastRow);
 
5938
        else
 
5939
            this.$updateRowLengthCache(firstRow, lastRow);
 
5940
 
 
5941
        return removedFolds;
 
5942
    };
 
5943
 
 
5944
    this.$updateRowLengthCache = function(firstRow, lastRow, b) {
 
5945
        this.$rowLengthCache[firstRow] = null;
 
5946
        this.$rowLengthCache[lastRow] = null;
 
5947
    };
 
5948
 
 
5949
    this.$updateWrapData = function(firstRow, lastRow) {
 
5950
        var lines = this.doc.getAllLines();
 
5951
        var tabSize = this.getTabSize();
 
5952
        var wrapData = this.$wrapData;
 
5953
        var wrapLimit = this.$wrapLimit;
 
5954
        var tokens;
 
5955
        var foldLine;
 
5956
 
 
5957
        var row = firstRow;
 
5958
        lastRow = Math.min(lastRow, lines.length - 1);
 
5959
        while (row <= lastRow) {
 
5960
            foldLine = this.getFoldLine(row, foldLine);
 
5961
            if (!foldLine) {
 
5962
                tokens = this.$getDisplayTokens(lang.stringTrimRight(lines[row]));
 
5963
                wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
 
5964
                row ++;
 
5965
            } else {
 
5966
                tokens = [];
 
5967
                foldLine.walk(function(placeholder, row, column, lastColumn) {
 
5968
                        var walkTokens;
 
5969
                        if (placeholder != null) {
 
5970
                            walkTokens = this.$getDisplayTokens(
 
5971
                                            placeholder, tokens.length);
 
5972
                            walkTokens[0] = PLACEHOLDER_START;
 
5973
                            for (var i = 1; i < walkTokens.length; i++) {
 
5974
                                walkTokens[i] = PLACEHOLDER_BODY;
 
5975
                            }
 
5976
                        } else {
 
5977
                            walkTokens = this.$getDisplayTokens(
 
5978
                                lines[row].substring(lastColumn, column),
 
5979
                                tokens.length);
 
5980
                        }
 
5981
                        tokens = tokens.concat(walkTokens);
 
5982
                    }.bind(this),
 
5983
                    foldLine.end.row,
 
5984
                    lines[foldLine.end.row].length + 1
 
5985
                );
 
5986
                while (tokens.length != 0 && tokens[tokens.length - 1] >= SPACE)
 
5987
                    tokens.pop();
 
5988
 
 
5989
                wrapData[foldLine.start.row]
 
5990
                    = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
 
5991
                row = foldLine.end.row + 1;
 
5992
            }
 
5993
        }
 
5994
    };
 
5995
    var CHAR = 1,
 
5996
        CHAR_EXT = 2,
 
5997
        PLACEHOLDER_START = 3,
 
5998
        PLACEHOLDER_BODY =  4,
 
5999
        PUNCTUATION = 9,
 
6000
        SPACE = 10,
 
6001
        TAB = 11,
 
6002
        TAB_SPACE = 12;
 
6003
 
 
6004
 
 
6005
    this.$computeWrapSplits = function(tokens, wrapLimit) {
 
6006
        if (tokens.length == 0) {
 
6007
            return [];
 
6008
        }
 
6009
 
 
6010
        var splits = [];
 
6011
        var displayLength = tokens.length;
 
6012
        var lastSplit = 0, lastDocSplit = 0;
 
6013
 
 
6014
        function addSplit(screenPos) {
 
6015
            var displayed = tokens.slice(lastSplit, screenPos);
 
6016
            var len = displayed.length;
 
6017
            displayed.join("").
 
6018
                replace(/12/g, function() {
 
6019
                    len -= 1;
 
6020
                }).
 
6021
                replace(/2/g, function() {
 
6022
                    len -= 1;
 
6023
                });
 
6024
 
 
6025
            lastDocSplit += len;
 
6026
            splits.push(lastDocSplit);
 
6027
            lastSplit = screenPos;
 
6028
        }
 
6029
 
 
6030
        while (displayLength - lastSplit > wrapLimit) {
 
6031
            var split = lastSplit + wrapLimit;
 
6032
            if (tokens[split] >= SPACE) {
 
6033
                while (tokens[split] >= SPACE) {
 
6034
                    split ++;
 
6035
                }
 
6036
                addSplit(split);
 
6037
                continue;
 
6038
            }
 
6039
            if (tokens[split] == PLACEHOLDER_START
 
6040
                || tokens[split] == PLACEHOLDER_BODY)
 
6041
            {
 
6042
                for (split; split != lastSplit - 1; split--) {
 
6043
                    if (tokens[split] == PLACEHOLDER_START) {
 
6044
                        break;
 
6045
                    }
 
6046
                }
 
6047
                if (split > lastSplit) {
 
6048
                    addSplit(split);
 
6049
                    continue;
 
6050
                }
 
6051
                split = lastSplit + wrapLimit;
 
6052
                for (split; split < tokens.length; split++) {
 
6053
                    if (tokens[split] != PLACEHOLDER_BODY)
 
6054
                    {
 
6055
                        break;
 
6056
                    }
 
6057
                }
 
6058
                if (split == tokens.length) {
 
6059
                    break;  // Breaks the while-loop.
 
6060
                }
 
6061
                addSplit(split);
 
6062
                continue;
 
6063
            }
 
6064
            var minSplit = Math.max(split - 10, lastSplit - 1);
 
6065
            while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
 
6066
                split --;
 
6067
            }
 
6068
            while (split > minSplit && tokens[split] == PUNCTUATION) {
 
6069
                split --;
 
6070
            }
 
6071
            if (split > minSplit) {
 
6072
                addSplit(++split);
 
6073
                continue;
 
6074
            }
 
6075
            split = lastSplit + wrapLimit;
 
6076
            addSplit(split);
 
6077
        }
 
6078
        return splits;
 
6079
    };
 
6080
    this.$getDisplayTokens = function(str, offset) {
 
6081
        var arr = [];
 
6082
        var tabSize;
 
6083
        offset = offset || 0;
 
6084
 
 
6085
        for (var i = 0; i < str.length; i++) {
 
6086
            var c = str.charCodeAt(i);
 
6087
            if (c == 9) {
 
6088
                tabSize = this.getScreenTabSize(arr.length + offset);
 
6089
                arr.push(TAB);
 
6090
                for (var n = 1; n < tabSize; n++) {
 
6091
                    arr.push(TAB_SPACE);
 
6092
                }
 
6093
            }
 
6094
            else if (c == 32) {
 
6095
                arr.push(SPACE);
 
6096
            } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {
 
6097
                arr.push(PUNCTUATION);
 
6098
            }
 
6099
            else if (c >= 0x1100 && isFullWidth(c)) {
 
6100
                arr.push(CHAR, CHAR_EXT);
 
6101
            } else {
 
6102
                arr.push(CHAR);
 
6103
            }
 
6104
        }
 
6105
        return arr;
 
6106
    };
 
6107
    this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
 
6108
        if (maxScreenColumn == 0)
 
6109
            return [0, 0];
 
6110
        if (maxScreenColumn == null)
 
6111
            maxScreenColumn = Infinity;
 
6112
        screenColumn = screenColumn || 0;
 
6113
 
 
6114
        var c, column;
 
6115
        for (column = 0; column < str.length; column++) {
 
6116
            c = str.charCodeAt(column);
 
6117
            if (c == 9) {
 
6118
                screenColumn += this.getScreenTabSize(screenColumn);
 
6119
            }
 
6120
            else if (c >= 0x1100 && isFullWidth(c)) {
 
6121
                screenColumn += 2;
 
6122
            } else {
 
6123
                screenColumn += 1;
 
6124
            }
 
6125
            if (screenColumn > maxScreenColumn) {
 
6126
                break;
 
6127
            }
 
6128
        }
 
6129
 
 
6130
        return [screenColumn, column];
 
6131
    };
 
6132
    this.getRowLength = function(row) {
 
6133
        if (!this.$useWrapMode || !this.$wrapData[row]) {
 
6134
            return 1;
 
6135
        } else {
 
6136
            return this.$wrapData[row].length + 1;
 
6137
        }
 
6138
    };
 
6139
    this.getScreenLastRowColumn = function(screenRow) {
 
6140
        var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
 
6141
        return this.documentToScreenColumn(pos.row, pos.column);
 
6142
    };
 
6143
    this.getDocumentLastRowColumn = function(docRow, docColumn) {
 
6144
        var screenRow = this.documentToScreenRow(docRow, docColumn);
 
6145
        return this.getScreenLastRowColumn(screenRow);
 
6146
    };
 
6147
    this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {
 
6148
        var screenRow = this.documentToScreenRow(docRow, docColumn);
 
6149
        return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
 
6150
    };
 
6151
    this.getRowSplitData = function(row) {
 
6152
        if (!this.$useWrapMode) {
 
6153
            return undefined;
 
6154
        } else {
 
6155
            return this.$wrapData[row];
 
6156
        }
 
6157
    };
 
6158
    this.getScreenTabSize = function(screenColumn) {
 
6159
        return this.$tabSize - screenColumn % this.$tabSize;
 
6160
    };
 
6161
 
 
6162
 
 
6163
    this.screenToDocumentRow = function(screenRow, screenColumn) {
 
6164
        return this.screenToDocumentPosition(screenRow, screenColumn).row;
 
6165
    };
 
6166
 
 
6167
 
 
6168
    this.screenToDocumentColumn = function(screenRow, screenColumn) {
 
6169
        return this.screenToDocumentPosition(screenRow, screenColumn).column;
 
6170
    };
 
6171
    this.screenToDocumentPosition = function(screenRow, screenColumn) {
 
6172
        if (screenRow < 0)
 
6173
            return {row: 0, column: 0};
 
6174
 
 
6175
        var line;
 
6176
        var docRow = 0;
 
6177
        var docColumn = 0;
 
6178
        var column;
 
6179
        var row = 0;
 
6180
        var rowLength = 0;
 
6181
 
 
6182
        var rowCache = this.$screenRowCache;
 
6183
        var i = this.$getRowCacheIndex(rowCache, screenRow);
 
6184
        var l = rowCache.length;
 
6185
        if (l && i >= 0) {
 
6186
            var row = rowCache[i];
 
6187
            var docRow = this.$docRowCache[i];
 
6188
            var doCache = screenRow > rowCache[l - 1];
 
6189
        } else {
 
6190
            var doCache = !l;
 
6191
        }
 
6192
 
 
6193
        var maxRow = this.getLength() - 1;
 
6194
        var foldLine = this.getNextFoldLine(docRow);
 
6195
        var foldStart = foldLine ? foldLine.start.row : Infinity;
 
6196
 
 
6197
        while (row <= screenRow) {
 
6198
            rowLength = this.getRowLength(docRow);
 
6199
            if (row + rowLength - 1 >= screenRow || docRow >= maxRow) {
 
6200
                break;
 
6201
            } else {
 
6202
                row += rowLength;
 
6203
                docRow++;
 
6204
                if (docRow > foldStart) {
 
6205
                    docRow = foldLine.end.row+1;
 
6206
                    foldLine = this.getNextFoldLine(docRow, foldLine);
 
6207
                    foldStart = foldLine ? foldLine.start.row : Infinity;
 
6208
                }
 
6209
            }
 
6210
 
 
6211
            if (doCache) {
 
6212
                this.$docRowCache.push(docRow);
 
6213
                this.$screenRowCache.push(row);
 
6214
            }
 
6215
        }
 
6216
 
 
6217
        if (foldLine && foldLine.start.row <= docRow) {
 
6218
            line = this.getFoldDisplayLine(foldLine);
 
6219
            docRow = foldLine.start.row;
 
6220
        } else if (row + rowLength <= screenRow || docRow > maxRow) {
 
6221
            return {
 
6222
                row: maxRow,
 
6223
                column: this.getLine(maxRow).length
 
6224
            }
 
6225
        } else {
 
6226
            line = this.getLine(docRow);
 
6227
            foldLine = null;
 
6228
        }
 
6229
 
 
6230
        if (this.$useWrapMode) {
 
6231
            var splits = this.$wrapData[docRow];
 
6232
            if (splits) {
 
6233
                column = splits[screenRow - row];
 
6234
                if(screenRow > row && splits.length) {
 
6235
                    docColumn = splits[screenRow - row - 1] || splits[splits.length - 1];
 
6236
                    line = line.substring(docColumn);
 
6237
                }
 
6238
            }
 
6239
        }
 
6240
 
 
6241
        docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
 
6242
        if (this.$useWrapMode && docColumn >= column)
 
6243
            docColumn = column - 1;
 
6244
 
 
6245
        if (foldLine)
 
6246
            return foldLine.idxToPosition(docColumn);
 
6247
 
 
6248
        return {row: docRow, column: docColumn};
 
6249
    };
 
6250
    this.documentToScreenPosition = function(docRow, docColumn) {
 
6251
        if (typeof docColumn === "undefined")
 
6252
            var pos = this.$clipPositionToDocument(docRow.row, docRow.column);
 
6253
        else
 
6254
            pos = this.$clipPositionToDocument(docRow, docColumn);
 
6255
 
 
6256
        docRow = pos.row;
 
6257
        docColumn = pos.column;
 
6258
 
 
6259
        var screenRow = 0;
 
6260
        var foldStartRow = null;
 
6261
        var fold = null;
 
6262
        fold = this.getFoldAt(docRow, docColumn, 1);
 
6263
        if (fold) {
 
6264
            docRow = fold.start.row;
 
6265
            docColumn = fold.start.column;
 
6266
        }
 
6267
 
 
6268
        var rowEnd, row = 0;
 
6269
 
 
6270
 
 
6271
        var rowCache = this.$docRowCache;
 
6272
        var i = this.$getRowCacheIndex(rowCache, docRow);
 
6273
        var l = rowCache.length;
 
6274
        if (l && i >= 0) {
 
6275
            var row = rowCache[i];
 
6276
            var screenRow = this.$screenRowCache[i];
 
6277
            var doCache = docRow > rowCache[l - 1];
 
6278
        } else {
 
6279
            var doCache = !l;
 
6280
        }
 
6281
 
 
6282
        var foldLine = this.getNextFoldLine(row);
 
6283
        var foldStart = foldLine ?foldLine.start.row :Infinity;
 
6284
 
 
6285
        while (row < docRow) {
 
6286
            if (row >= foldStart) {
 
6287
                rowEnd = foldLine.end.row + 1;
 
6288
                if (rowEnd > docRow)
 
6289
                    break;
 
6290
                foldLine = this.getNextFoldLine(rowEnd, foldLine);
 
6291
                foldStart = foldLine ?foldLine.start.row :Infinity;
 
6292
            }
 
6293
            else {
 
6294
                rowEnd = row + 1;
 
6295
            }
 
6296
 
 
6297
            screenRow += this.getRowLength(row);
 
6298
            row = rowEnd;
 
6299
 
 
6300
            if (doCache) {
 
6301
                this.$docRowCache.push(row);
 
6302
                this.$screenRowCache.push(screenRow);
 
6303
            }
 
6304
        }
 
6305
        var textLine = "";
 
6306
        if (foldLine && row >= foldStart) {
 
6307
            textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);
 
6308
            foldStartRow = foldLine.start.row;
 
6309
        } else {
 
6310
            textLine = this.getLine(docRow).substring(0, docColumn);
 
6311
            foldStartRow = docRow;
 
6312
        }
 
6313
        if (this.$useWrapMode) {
 
6314
            var wrapRow = this.$wrapData[foldStartRow];
 
6315
            var screenRowOffset = 0;
 
6316
            while (textLine.length >= wrapRow[screenRowOffset]) {
 
6317
                screenRow ++;
 
6318
                screenRowOffset++;
 
6319
            }
 
6320
            textLine = textLine.substring(
 
6321
                wrapRow[screenRowOffset - 1] || 0, textLine.length
 
6322
            );
 
6323
        }
 
6324
 
 
6325
        return {
 
6326
            row: screenRow,
 
6327
            column: this.$getStringScreenWidth(textLine)[0]
 
6328
        };
 
6329
    };
 
6330
    this.documentToScreenColumn = function(row, docColumn) {
 
6331
        return this.documentToScreenPosition(row, docColumn).column;
 
6332
    };
 
6333
    this.documentToScreenRow = function(docRow, docColumn) {
 
6334
        return this.documentToScreenPosition(docRow, docColumn).row;
 
6335
    };
 
6336
    this.getScreenLength = function() {
 
6337
        var screenRows = 0;
 
6338
        var fold = null;
 
6339
        if (!this.$useWrapMode) {
 
6340
            screenRows = this.getLength();
 
6341
            var foldData = this.$foldData;
 
6342
            for (var i = 0; i < foldData.length; i++) {
 
6343
                fold = foldData[i];
 
6344
                screenRows -= fold.end.row - fold.start.row;
 
6345
            }
 
6346
        } else {
 
6347
            var lastRow = this.$wrapData.length;
 
6348
            var row = 0, i = 0;
 
6349
            var fold = this.$foldData[i++];
 
6350
            var foldStart = fold ? fold.start.row :Infinity;
 
6351
 
 
6352
            while (row < lastRow) {
 
6353
                screenRows += this.$wrapData[row].length + 1;
 
6354
                row ++;
 
6355
                if (row > foldStart) {
 
6356
                    row = fold.end.row+1;
 
6357
                    fold = this.$foldData[i++];
 
6358
                    foldStart = fold ?fold.start.row :Infinity;
 
6359
                }
 
6360
            }
 
6361
        }
 
6362
 
 
6363
        return screenRows;
 
6364
    };
 
6365
    function isFullWidth(c) {
 
6366
        if (c < 0x1100)
 
6367
            return false;
 
6368
        return c >= 0x1100 && c <= 0x115F ||
 
6369
               c >= 0x11A3 && c <= 0x11A7 ||
 
6370
               c >= 0x11FA && c <= 0x11FF ||
 
6371
               c >= 0x2329 && c <= 0x232A ||
 
6372
               c >= 0x2E80 && c <= 0x2E99 ||
 
6373
               c >= 0x2E9B && c <= 0x2EF3 ||
 
6374
               c >= 0x2F00 && c <= 0x2FD5 ||
 
6375
               c >= 0x2FF0 && c <= 0x2FFB ||
 
6376
               c >= 0x3000 && c <= 0x303E ||
 
6377
               c >= 0x3041 && c <= 0x3096 ||
 
6378
               c >= 0x3099 && c <= 0x30FF ||
 
6379
               c >= 0x3105 && c <= 0x312D ||
 
6380
               c >= 0x3131 && c <= 0x318E ||
 
6381
               c >= 0x3190 && c <= 0x31BA ||
 
6382
               c >= 0x31C0 && c <= 0x31E3 ||
 
6383
               c >= 0x31F0 && c <= 0x321E ||
 
6384
               c >= 0x3220 && c <= 0x3247 ||
 
6385
               c >= 0x3250 && c <= 0x32FE ||
 
6386
               c >= 0x3300 && c <= 0x4DBF ||
 
6387
               c >= 0x4E00 && c <= 0xA48C ||
 
6388
               c >= 0xA490 && c <= 0xA4C6 ||
 
6389
               c >= 0xA960 && c <= 0xA97C ||
 
6390
               c >= 0xAC00 && c <= 0xD7A3 ||
 
6391
               c >= 0xD7B0 && c <= 0xD7C6 ||
 
6392
               c >= 0xD7CB && c <= 0xD7FB ||
 
6393
               c >= 0xF900 && c <= 0xFAFF ||
 
6394
               c >= 0xFE10 && c <= 0xFE19 ||
 
6395
               c >= 0xFE30 && c <= 0xFE52 ||
 
6396
               c >= 0xFE54 && c <= 0xFE66 ||
 
6397
               c >= 0xFE68 && c <= 0xFE6B ||
 
6398
               c >= 0xFF01 && c <= 0xFF60 ||
 
6399
               c >= 0xFFE0 && c <= 0xFFE6;
 
6400
    };
 
6401
 
 
6402
}).call(EditSession.prototype);
 
6403
 
 
6404
require("./edit_session/folding").Folding.call(EditSession.prototype);
 
6405
require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype);
 
6406
 
 
6407
 
 
6408
config.defineOptions(EditSession.prototype, "session", {
 
6409
    wrap: {
 
6410
        set: function(value) {
 
6411
            if (!value || value == "off")
 
6412
                value = false;
 
6413
            else if (value == "free")
 
6414
                value = true;
 
6415
            else if (typeof value == "string")
 
6416
                value = parseInt(value, 10) || false;
 
6417
 
 
6418
            if (!value) {
 
6419
                this.setUseWrapMode(false);
 
6420
            } else {
 
6421
                var col = typeof value == "number" ? value : null;
 
6422
                this.setUseWrapMode(true);
 
6423
                this.setWrapLimitRange(col, col);
 
6424
            }
 
6425
            this.$wrap = value;
 
6426
        },
 
6427
        get: function() {
 
6428
            return this.getUseWrapMode() ? this.getWrapLimitRange().min || "free" : "off";
 
6429
        },
 
6430
        handlesSet: true
 
6431
    },
 
6432
    firstLineNumber: {
 
6433
        set: function() {this._emit("changeBreakpoint");},
 
6434
        initialValue: 1
 
6435
    },
 
6436
    useWorker: {
 
6437
        set: function(useWorker) {
 
6438
            this.$useWorker = useWorker;
 
6439
 
 
6440
            this.$stopWorker();
 
6441
            if (useWorker)
 
6442
                this.$startWorker();
 
6443
        },
 
6444
        initialValue: true
 
6445
    },
 
6446
    useSoftTabs: {initialValue: true},
 
6447
    tabSize: {
 
6448
        set: function(tabSize) {
 
6449
            if (isNaN(tabSize) || this.$tabSize === tabSize) return;
 
6450
 
 
6451
            this.$modified = true;
 
6452
            this.$rowLengthCache = [];
 
6453
            this.$tabSize = tabSize;
 
6454
            this._emit("changeTabSize");
 
6455
        },
 
6456
        initialValue: 4,
 
6457
        handlesSet: true
 
6458
    }
 
6459
});
 
6460
 
 
6461
exports.EditSession = EditSession;
 
6462
});
 
6463
 
 
6464
define('ace/selection', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter', 'ace/range'], function(require, exports, module) {
 
6465
 
 
6466
 
 
6467
var oop = require("./lib/oop");
 
6468
var lang = require("./lib/lang");
 
6469
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
6470
var Range = require("./range").Range;
 
6471
var Selection = function(session) {
 
6472
    this.session = session;
 
6473
    this.doc = session.getDocument();
 
6474
 
 
6475
    this.clearSelection();
 
6476
    this.lead = this.selectionLead = this.doc.createAnchor(0, 0);
 
6477
    this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);
 
6478
 
 
6479
    var self = this;
 
6480
    this.lead.on("change", function(e) {
 
6481
        self._emit("changeCursor");
 
6482
        if (!self.$isEmpty)
 
6483
            self._emit("changeSelection");
 
6484
        if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)
 
6485
            self.$desiredColumn = null;
 
6486
    });
 
6487
 
 
6488
    this.selectionAnchor.on("change", function() {
 
6489
        if (!self.$isEmpty)
 
6490
            self._emit("changeSelection");
 
6491
    });
 
6492
};
 
6493
 
 
6494
(function() {
 
6495
 
 
6496
    oop.implement(this, EventEmitter);
 
6497
    this.isEmpty = function() {
 
6498
        return (this.$isEmpty || (
 
6499
            this.anchor.row == this.lead.row &&
 
6500
            this.anchor.column == this.lead.column
 
6501
        ));
 
6502
    };
 
6503
    this.isMultiLine = function() {
 
6504
        if (this.isEmpty()) {
 
6505
            return false;
 
6506
        }
 
6507
 
 
6508
        return this.getRange().isMultiLine();
 
6509
    };
 
6510
    this.getCursor = function() {
 
6511
        return this.lead.getPosition();
 
6512
    };
 
6513
    this.setSelectionAnchor = function(row, column) {
 
6514
        this.anchor.setPosition(row, column);
 
6515
 
 
6516
        if (this.$isEmpty) {
 
6517
            this.$isEmpty = false;
 
6518
            this._emit("changeSelection");
 
6519
        }
 
6520
    };
 
6521
    this.getSelectionAnchor = function() {
 
6522
        if (this.$isEmpty)
 
6523
            return this.getSelectionLead()
 
6524
        else
 
6525
            return this.anchor.getPosition();
 
6526
    };
 
6527
    this.getSelectionLead = function() {
 
6528
        return this.lead.getPosition();
 
6529
    };
 
6530
    this.shiftSelection = function(columns) {
 
6531
        if (this.$isEmpty) {
 
6532
            this.moveCursorTo(this.lead.row, this.lead.column + columns);
 
6533
            return;
 
6534
        };
 
6535
 
 
6536
        var anchor = this.getSelectionAnchor();
 
6537
        var lead = this.getSelectionLead();
 
6538
 
 
6539
        var isBackwards = this.isBackwards();
 
6540
 
 
6541
        if (!isBackwards || anchor.column !== 0)
 
6542
            this.setSelectionAnchor(anchor.row, anchor.column + columns);
 
6543
 
 
6544
        if (isBackwards || lead.column !== 0) {
 
6545
            this.$moveSelection(function() {
 
6546
                this.moveCursorTo(lead.row, lead.column + columns);
 
6547
            });
 
6548
        }
 
6549
    };
 
6550
    this.isBackwards = function() {
 
6551
        var anchor = this.anchor;
 
6552
        var lead = this.lead;
 
6553
        return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
 
6554
    };
 
6555
    this.getRange = function() {
 
6556
        var anchor = this.anchor;
 
6557
        var lead = this.lead;
 
6558
 
 
6559
        if (this.isEmpty())
 
6560
            return Range.fromPoints(lead, lead);
 
6561
 
 
6562
        if (this.isBackwards()) {
 
6563
            return Range.fromPoints(lead, anchor);
 
6564
        }
 
6565
        else {
 
6566
            return Range.fromPoints(anchor, lead);
 
6567
        }
 
6568
    };
 
6569
    this.clearSelection = function() {
 
6570
        if (!this.$isEmpty) {
 
6571
            this.$isEmpty = true;
 
6572
            this._emit("changeSelection");
 
6573
        }
 
6574
    };
 
6575
    this.selectAll = function() {
 
6576
        var lastRow = this.doc.getLength() - 1;
 
6577
        this.setSelectionAnchor(0, 0);
 
6578
        this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length);
 
6579
    };
 
6580
    this.setRange =
 
6581
    this.setSelectionRange = function(range, reverse) {
 
6582
        if (reverse) {
 
6583
            this.setSelectionAnchor(range.end.row, range.end.column);
 
6584
            this.selectTo(range.start.row, range.start.column);
 
6585
        } else {
 
6586
            this.setSelectionAnchor(range.start.row, range.start.column);
 
6587
            this.selectTo(range.end.row, range.end.column);
 
6588
        }
 
6589
        this.$desiredColumn = null;
 
6590
    };
 
6591
 
 
6592
    this.$moveSelection = function(mover) {
 
6593
        var lead = this.lead;
 
6594
        if (this.$isEmpty)
 
6595
            this.setSelectionAnchor(lead.row, lead.column);
 
6596
 
 
6597
        mover.call(this);
 
6598
    };
 
6599
    this.selectTo = function(row, column) {
 
6600
        this.$moveSelection(function() {
 
6601
            this.moveCursorTo(row, column);
 
6602
        });
 
6603
    };
 
6604
    this.selectToPosition = function(pos) {
 
6605
        this.$moveSelection(function() {
 
6606
            this.moveCursorToPosition(pos);
 
6607
        });
 
6608
    };
 
6609
    this.selectUp = function() {
 
6610
        this.$moveSelection(this.moveCursorUp);
 
6611
    };
 
6612
    this.selectDown = function() {
 
6613
        this.$moveSelection(this.moveCursorDown);
 
6614
    };
 
6615
    this.selectRight = function() {
 
6616
        this.$moveSelection(this.moveCursorRight);
 
6617
    };
 
6618
    this.selectLeft = function() {
 
6619
        this.$moveSelection(this.moveCursorLeft);
 
6620
    };
 
6621
    this.selectLineStart = function() {
 
6622
        this.$moveSelection(this.moveCursorLineStart);
 
6623
    };
 
6624
    this.selectLineEnd = function() {
 
6625
        this.$moveSelection(this.moveCursorLineEnd);
 
6626
    };
 
6627
    this.selectFileEnd = function() {
 
6628
        this.$moveSelection(this.moveCursorFileEnd);
 
6629
    };
 
6630
    this.selectFileStart = function() {
 
6631
        this.$moveSelection(this.moveCursorFileStart);
 
6632
    };
 
6633
    this.selectWordRight = function() {
 
6634
        this.$moveSelection(this.moveCursorWordRight);
 
6635
    };
 
6636
    this.selectWordLeft = function() {
 
6637
        this.$moveSelection(this.moveCursorWordLeft);
 
6638
    };
 
6639
    this.getWordRange = function(row, column) {
 
6640
        if (typeof column == "undefined") {
 
6641
            var cursor = row || this.lead;
 
6642
            row = cursor.row;
 
6643
            column = cursor.column;
 
6644
        }
 
6645
        return this.session.getWordRange(row, column);
 
6646
    };
 
6647
    this.selectWord = function() {
 
6648
        this.setSelectionRange(this.getWordRange());
 
6649
    };
 
6650
    this.selectAWord = function() {
 
6651
        var cursor = this.getCursor();
 
6652
        var range = this.session.getAWordRange(cursor.row, cursor.column);
 
6653
        this.setSelectionRange(range);
 
6654
    };
 
6655
 
 
6656
    this.getLineRange = function(row, excludeLastChar) {
 
6657
        var rowStart = typeof row == "number" ? row : this.lead.row;
 
6658
        var rowEnd;
 
6659
 
 
6660
        var foldLine = this.session.getFoldLine(rowStart);
 
6661
        if (foldLine) {
 
6662
            rowStart = foldLine.start.row;
 
6663
            rowEnd = foldLine.end.row;
 
6664
        } else {
 
6665
            rowEnd = rowStart;
 
6666
        }
 
6667
        if (excludeLastChar)
 
6668
            return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);
 
6669
        else
 
6670
            return new Range(rowStart, 0, rowEnd + 1, 0);
 
6671
    };
 
6672
    this.selectLine = function() {
 
6673
        this.setSelectionRange(this.getLineRange());
 
6674
    };
 
6675
    this.moveCursorUp = function() {
 
6676
        this.moveCursorBy(-1, 0);
 
6677
    };
 
6678
    this.moveCursorDown = function() {
 
6679
        this.moveCursorBy(1, 0);
 
6680
    };
 
6681
    this.moveCursorLeft = function() {
 
6682
        var cursor = this.lead.getPosition(),
 
6683
            fold;
 
6684
 
 
6685
        if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
 
6686
            this.moveCursorTo(fold.start.row, fold.start.column);
 
6687
        } else if (cursor.column == 0) {
 
6688
            if (cursor.row > 0) {
 
6689
                this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
 
6690
            }
 
6691
        }
 
6692
        else {
 
6693
            var tabSize = this.session.getTabSize();
 
6694
            if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize)
 
6695
                this.moveCursorBy(0, -tabSize);
 
6696
            else
 
6697
                this.moveCursorBy(0, -1);
 
6698
        }
 
6699
    };
 
6700
    this.moveCursorRight = function() {
 
6701
        var cursor = this.lead.getPosition(),
 
6702
            fold;
 
6703
        if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
 
6704
            this.moveCursorTo(fold.end.row, fold.end.column);
 
6705
        }
 
6706
        else if (this.lead.column == this.doc.getLine(this.lead.row).length) {
 
6707
            if (this.lead.row < this.doc.getLength() - 1) {
 
6708
                this.moveCursorTo(this.lead.row + 1, 0);
 
6709
            }
 
6710
        }
 
6711
        else {
 
6712
            var tabSize = this.session.getTabSize();
 
6713
            var cursor = this.lead;
 
6714
            if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize)
 
6715
                this.moveCursorBy(0, tabSize);
 
6716
            else
 
6717
                this.moveCursorBy(0, 1);
 
6718
        }
 
6719
    };
 
6720
    this.moveCursorLineStart = function() {
 
6721
        var row = this.lead.row;
 
6722
        var column = this.lead.column;
 
6723
        var screenRow = this.session.documentToScreenRow(row, column);
 
6724
        var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);
 
6725
        var beforeCursor = this.session.getDisplayLine(
 
6726
            row, null, firstColumnPosition.row,
 
6727
            firstColumnPosition.column
 
6728
        );
 
6729
 
 
6730
        var leadingSpace = beforeCursor.match(/^\s*/);
 
6731
        if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)
 
6732
            firstColumnPosition.column += leadingSpace[0].length;
 
6733
        this.moveCursorToPosition(firstColumnPosition);
 
6734
    };
 
6735
    this.moveCursorLineEnd = function() {
 
6736
        var lead = this.lead;
 
6737
        var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
 
6738
        if (this.lead.column == lineEnd.column) {
 
6739
            var line = this.session.getLine(lineEnd.row);
 
6740
            if (lineEnd.column == line.length) {
 
6741
                var textEnd = line.search(/\s+$/);
 
6742
                if (textEnd > 0)
 
6743
                    lineEnd.column = textEnd;
 
6744
            }
 
6745
        }
 
6746
 
 
6747
        this.moveCursorTo(lineEnd.row, lineEnd.column);
 
6748
    };
 
6749
    this.moveCursorFileEnd = function() {
 
6750
        var row = this.doc.getLength() - 1;
 
6751
        var column = this.doc.getLine(row).length;
 
6752
        this.moveCursorTo(row, column);
 
6753
    };
 
6754
    this.moveCursorFileStart = function() {
 
6755
        this.moveCursorTo(0, 0);
 
6756
    };
 
6757
    this.moveCursorLongWordRight = function() {
 
6758
        var row = this.lead.row;
 
6759
        var column = this.lead.column;
 
6760
        var line = this.doc.getLine(row);
 
6761
        var rightOfCursor = line.substring(column);
 
6762
 
 
6763
        var match;
 
6764
        this.session.nonTokenRe.lastIndex = 0;
 
6765
        this.session.tokenRe.lastIndex = 0;
 
6766
        var fold = this.session.getFoldAt(row, column, 1);
 
6767
        if (fold) {
 
6768
            this.moveCursorTo(fold.end.row, fold.end.column);
 
6769
            return;
 
6770
        }
 
6771
        if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
 
6772
            column += this.session.nonTokenRe.lastIndex;
 
6773
            this.session.nonTokenRe.lastIndex = 0;
 
6774
            rightOfCursor = line.substring(column);
 
6775
        }
 
6776
        if (column >= line.length) {
 
6777
            this.moveCursorTo(row, line.length);
 
6778
            this.moveCursorRight();
 
6779
            if (row < this.doc.getLength() - 1)
 
6780
                this.moveCursorWordRight();
 
6781
            return;
 
6782
        }
 
6783
        if (match = this.session.tokenRe.exec(rightOfCursor)) {
 
6784
            column += this.session.tokenRe.lastIndex;
 
6785
            this.session.tokenRe.lastIndex = 0;
 
6786
        }
 
6787
 
 
6788
        this.moveCursorTo(row, column);
 
6789
    };
 
6790
    this.moveCursorLongWordLeft = function() {
 
6791
        var row = this.lead.row;
 
6792
        var column = this.lead.column;
 
6793
        var fold;
 
6794
        if (fold = this.session.getFoldAt(row, column, -1)) {
 
6795
            this.moveCursorTo(fold.start.row, fold.start.column);
 
6796
            return;
 
6797
        }
 
6798
 
 
6799
        var str = this.session.getFoldStringAt(row, column, -1);
 
6800
        if (str == null) {
 
6801
            str = this.doc.getLine(row).substring(0, column)
 
6802
        }
 
6803
 
 
6804
        var leftOfCursor = lang.stringReverse(str);
 
6805
        var match;
 
6806
        this.session.nonTokenRe.lastIndex = 0;
 
6807
        this.session.tokenRe.lastIndex = 0;
 
6808
        if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
 
6809
            column -= this.session.nonTokenRe.lastIndex;
 
6810
            leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
 
6811
            this.session.nonTokenRe.lastIndex = 0;
 
6812
        }
 
6813
        if (column <= 0) {
 
6814
            this.moveCursorTo(row, 0);
 
6815
            this.moveCursorLeft();
 
6816
            if (row > 0)
 
6817
                this.moveCursorWordLeft();
 
6818
            return;
 
6819
        }
 
6820
        if (match = this.session.tokenRe.exec(leftOfCursor)) {
 
6821
            column -= this.session.tokenRe.lastIndex;
 
6822
            this.session.tokenRe.lastIndex = 0;
 
6823
        }
 
6824
 
 
6825
        this.moveCursorTo(row, column);
 
6826
    };
 
6827
 
 
6828
    this.$shortWordEndIndex = function(rightOfCursor) {
 
6829
        var match, index = 0, ch;
 
6830
        var whitespaceRe = /\s/;
 
6831
        var tokenRe = this.session.tokenRe;
 
6832
 
 
6833
        tokenRe.lastIndex = 0;
 
6834
        if (match = this.session.tokenRe.exec(rightOfCursor)) {
 
6835
            index = this.session.tokenRe.lastIndex;
 
6836
        } else {
 
6837
            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
 
6838
                index ++;
 
6839
 
 
6840
            if (index <= 1) {
 
6841
                tokenRe.lastIndex = 0;
 
6842
                 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {
 
6843
                    tokenRe.lastIndex = 0;
 
6844
                    index ++;
 
6845
                    if (whitespaceRe.test(ch)) {
 
6846
                        if (index > 2) {
 
6847
                            index--
 
6848
                            break;
 
6849
                        } else {
 
6850
                            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
 
6851
                                index ++;
 
6852
                            if (index > 2)
 
6853
                                break
 
6854
                        }
 
6855
                    }
 
6856
                }
 
6857
            }
 
6858
        }
 
6859
        tokenRe.lastIndex = 0;
 
6860
 
 
6861
        return index;
 
6862
    };
 
6863
 
 
6864
    this.moveCursorShortWordRight = function() {
 
6865
        var row = this.lead.row;
 
6866
        var column = this.lead.column;
 
6867
        var line = this.doc.getLine(row);
 
6868
        var rightOfCursor = line.substring(column);
 
6869
 
 
6870
        var fold = this.session.getFoldAt(row, column, 1);
 
6871
        if (fold)
 
6872
            return this.moveCursorTo(fold.end.row, fold.end.column);
 
6873
 
 
6874
        if (column == line.length) {
 
6875
            var l = this.doc.getLength();
 
6876
            do {    
 
6877
                row++;
 
6878
                rightOfCursor = this.doc.getLine(row)
 
6879
            } while (row < l && /^\s*$/.test(rightOfCursor))
 
6880
            
 
6881
            if (!/^\s+/.test(rightOfCursor))
 
6882
                rightOfCursor = ""
 
6883
            column = 0;
 
6884
        }
 
6885
 
 
6886
        var index = this.$shortWordEndIndex(rightOfCursor);
 
6887
 
 
6888
        this.moveCursorTo(row, column + index);
 
6889
    };
 
6890
 
 
6891
    this.moveCursorShortWordLeft = function() {
 
6892
        var row = this.lead.row;
 
6893
        var column = this.lead.column;
 
6894
 
 
6895
        var fold;
 
6896
        if (fold = this.session.getFoldAt(row, column, -1))
 
6897
            return this.moveCursorTo(fold.start.row, fold.start.column);
 
6898
 
 
6899
        var line = this.session.getLine(row).substring(0, column);
 
6900
        if (column == 0) {
 
6901
            do {    
 
6902
                row--;
 
6903
                line = this.doc.getLine(row);
 
6904
            } while (row > 0 && /^\s*$/.test(line))
 
6905
            
 
6906
            column = line.length;
 
6907
            if (!/\s+$/.test(line))
 
6908
                line = ""
 
6909
        }
 
6910
 
 
6911
        var leftOfCursor = lang.stringReverse(line);
 
6912
        var index = this.$shortWordEndIndex(leftOfCursor);
 
6913
 
 
6914
        return this.moveCursorTo(row, column - index);
 
6915
    };
 
6916
 
 
6917
    this.moveCursorWordRight = function() {
 
6918
        if (this.session.$selectLongWords)
 
6919
            this.moveCursorLongWordRight();
 
6920
        else
 
6921
            this.moveCursorShortWordRight();
 
6922
    };
 
6923
 
 
6924
    this.moveCursorWordLeft = function() {
 
6925
        if (this.session.$selectLongWords)
 
6926
            this.moveCursorLongWordLeft();
 
6927
        else
 
6928
            this.moveCursorShortWordLeft();
 
6929
    };
 
6930
    this.moveCursorBy = function(rows, chars) {
 
6931
        var screenPos = this.session.documentToScreenPosition(
 
6932
            this.lead.row,
 
6933
            this.lead.column
 
6934
        );
 
6935
 
 
6936
        if (chars === 0) {
 
6937
            if (this.$desiredColumn)
 
6938
                screenPos.column = this.$desiredColumn;
 
6939
            else
 
6940
                this.$desiredColumn = screenPos.column;
 
6941
        }
 
6942
 
 
6943
        var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column);
 
6944
        this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
 
6945
    };
 
6946
    this.moveCursorToPosition = function(position) {
 
6947
        this.moveCursorTo(position.row, position.column);
 
6948
    };
 
6949
    this.moveCursorTo = function(row, column, keepDesiredColumn) {
 
6950
        var fold = this.session.getFoldAt(row, column, 1);
 
6951
        if (fold) {
 
6952
            row = fold.start.row;
 
6953
            column = fold.start.column;
 
6954
        }
 
6955
 
 
6956
        this.$keepDesiredColumnOnChange = true;
 
6957
        this.lead.setPosition(row, column);
 
6958
        this.$keepDesiredColumnOnChange = false;
 
6959
 
 
6960
        if (!keepDesiredColumn)
 
6961
            this.$desiredColumn = null;
 
6962
    };
 
6963
    this.moveCursorToScreen = function(row, column, keepDesiredColumn) {
 
6964
        var pos = this.session.screenToDocumentPosition(row, column);
 
6965
        this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);
 
6966
    };
 
6967
    this.detach = function() {
 
6968
        this.lead.detach();
 
6969
        this.anchor.detach();
 
6970
        this.session = this.doc = null;
 
6971
    }
 
6972
 
 
6973
    this.fromOrientedRange = function(range) {
 
6974
        this.setSelectionRange(range, range.cursor == range.start);
 
6975
        this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
 
6976
    }
 
6977
 
 
6978
    this.toOrientedRange = function(range) {
 
6979
        var r = this.getRange();
 
6980
        if (range) {
 
6981
            range.start.column = r.start.column;
 
6982
            range.start.row = r.start.row;
 
6983
            range.end.column = r.end.column;
 
6984
            range.end.row = r.end.row;
 
6985
        } else {
 
6986
            range = r;
 
6987
        }
 
6988
 
 
6989
        range.cursor = this.isBackwards() ? range.start : range.end;
 
6990
        range.desiredColumn = this.$desiredColumn;
 
6991
        return range;
 
6992
    }
 
6993
 
 
6994
}).call(Selection.prototype);
 
6995
 
 
6996
exports.Selection = Selection;
 
6997
});
 
6998
 
 
6999
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
 
7000
 
 
7001
var comparePoints = function(p1, p2) {
 
7002
    return p1.row - p2.row || p1.column - p2.column;
 
7003
};
 
7004
var Range = function(startRow, startColumn, endRow, endColumn) {
 
7005
    this.start = {
 
7006
        row: startRow,
 
7007
        column: startColumn
 
7008
    };
 
7009
 
 
7010
    this.end = {
 
7011
        row: endRow,
 
7012
        column: endColumn
 
7013
    };
 
7014
};
 
7015
 
 
7016
(function() {
 
7017
    this.isEqual = function(range) {
 
7018
        return this.start.row === range.start.row &&
 
7019
            this.end.row === range.end.row &&
 
7020
            this.start.column === range.start.column &&
 
7021
            this.end.column === range.end.column;
 
7022
    };
 
7023
    this.toString = function() {
 
7024
        return ("Range: [" + this.start.row + "/" + this.start.column +
 
7025
            "] -> [" + this.end.row + "/" + this.end.column + "]");
 
7026
    };
 
7027
 
 
7028
    this.contains = function(row, column) {
 
7029
        return this.compare(row, column) == 0;
 
7030
    };
 
7031
    this.compareRange = function(range) {
 
7032
        var cmp,
 
7033
            end = range.end,
 
7034
            start = range.start;
 
7035
 
 
7036
        cmp = this.compare(end.row, end.column);
 
7037
        if (cmp == 1) {
 
7038
            cmp = this.compare(start.row, start.column);
 
7039
            if (cmp == 1) {
 
7040
                return 2;
 
7041
            } else if (cmp == 0) {
 
7042
                return 1;
 
7043
            } else {
 
7044
                return 0;
 
7045
            }
 
7046
        } else if (cmp == -1) {
 
7047
            return -2;
 
7048
        } else {
 
7049
            cmp = this.compare(start.row, start.column);
 
7050
            if (cmp == -1) {
 
7051
                return -1;
 
7052
            } else if (cmp == 1) {
 
7053
                return 42;
 
7054
            } else {
 
7055
                return 0;
 
7056
            }
 
7057
        }
 
7058
    };
 
7059
    this.comparePoint = function(p) {
 
7060
        return this.compare(p.row, p.column);
 
7061
    };
 
7062
    this.containsRange = function(range) {
 
7063
        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
 
7064
    };
 
7065
    this.intersects = function(range) {
 
7066
        var cmp = this.compareRange(range);
 
7067
        return (cmp == -1 || cmp == 0 || cmp == 1);
 
7068
    };
 
7069
    this.isEnd = function(row, column) {
 
7070
        return this.end.row == row && this.end.column == column;
 
7071
    };
 
7072
    this.isStart = function(row, column) {
 
7073
        return this.start.row == row && this.start.column == column;
 
7074
    };
 
7075
    this.setStart = function(row, column) {
 
7076
        if (typeof row == "object") {
 
7077
            this.start.column = row.column;
 
7078
            this.start.row = row.row;
 
7079
        } else {
 
7080
            this.start.row = row;
 
7081
            this.start.column = column;
 
7082
        }
 
7083
    };
 
7084
    this.setEnd = function(row, column) {
 
7085
        if (typeof row == "object") {
 
7086
            this.end.column = row.column;
 
7087
            this.end.row = row.row;
 
7088
        } else {
 
7089
            this.end.row = row;
 
7090
            this.end.column = column;
 
7091
        }
 
7092
    };
 
7093
    this.inside = function(row, column) {
 
7094
        if (this.compare(row, column) == 0) {
 
7095
            if (this.isEnd(row, column) || this.isStart(row, column)) {
 
7096
                return false;
 
7097
            } else {
 
7098
                return true;
 
7099
            }
 
7100
        }
 
7101
        return false;
 
7102
    };
 
7103
    this.insideStart = function(row, column) {
 
7104
        if (this.compare(row, column) == 0) {
 
7105
            if (this.isEnd(row, column)) {
 
7106
                return false;
 
7107
            } else {
 
7108
                return true;
 
7109
            }
 
7110
        }
 
7111
        return false;
 
7112
    };
 
7113
    this.insideEnd = function(row, column) {
 
7114
        if (this.compare(row, column) == 0) {
 
7115
            if (this.isStart(row, column)) {
 
7116
                return false;
 
7117
            } else {
 
7118
                return true;
 
7119
            }
 
7120
        }
 
7121
        return false;
 
7122
    };
 
7123
    this.compare = function(row, column) {
 
7124
        if (!this.isMultiLine()) {
 
7125
            if (row === this.start.row) {
 
7126
                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
 
7127
            };
 
7128
        }
 
7129
 
 
7130
        if (row < this.start.row)
 
7131
            return -1;
 
7132
 
 
7133
        if (row > this.end.row)
 
7134
            return 1;
 
7135
 
 
7136
        if (this.start.row === row)
 
7137
            return column >= this.start.column ? 0 : -1;
 
7138
 
 
7139
        if (this.end.row === row)
 
7140
            return column <= this.end.column ? 0 : 1;
 
7141
 
 
7142
        return 0;
 
7143
    };
 
7144
    this.compareStart = function(row, column) {
 
7145
        if (this.start.row == row && this.start.column == column) {
 
7146
            return -1;
 
7147
        } else {
 
7148
            return this.compare(row, column);
 
7149
        }
 
7150
    };
 
7151
    this.compareEnd = function(row, column) {
 
7152
        if (this.end.row == row && this.end.column == column) {
 
7153
            return 1;
 
7154
        } else {
 
7155
            return this.compare(row, column);
 
7156
        }
 
7157
    };
 
7158
    this.compareInside = function(row, column) {
 
7159
        if (this.end.row == row && this.end.column == column) {
 
7160
            return 1;
 
7161
        } else if (this.start.row == row && this.start.column == column) {
 
7162
            return -1;
 
7163
        } else {
 
7164
            return this.compare(row, column);
 
7165
        }
 
7166
    };
 
7167
    this.clipRows = function(firstRow, lastRow) {
 
7168
        if (this.end.row > lastRow)
 
7169
            var end = {row: lastRow + 1, column: 0};
 
7170
        else if (this.end.row < firstRow)
 
7171
            var end = {row: firstRow, column: 0};
 
7172
 
 
7173
        if (this.start.row > lastRow)
 
7174
            var start = {row: lastRow + 1, column: 0};
 
7175
        else if (this.start.row < firstRow)
 
7176
            var start = {row: firstRow, column: 0};
 
7177
 
 
7178
        return Range.fromPoints(start || this.start, end || this.end);
 
7179
    };
 
7180
    this.extend = function(row, column) {
 
7181
        var cmp = this.compare(row, column);
 
7182
 
 
7183
        if (cmp == 0)
 
7184
            return this;
 
7185
        else if (cmp == -1)
 
7186
            var start = {row: row, column: column};
 
7187
        else
 
7188
            var end = {row: row, column: column};
 
7189
 
 
7190
        return Range.fromPoints(start || this.start, end || this.end);
 
7191
    };
 
7192
 
 
7193
    this.isEmpty = function() {
 
7194
        return (this.start.row === this.end.row && this.start.column === this.end.column);
 
7195
    };
 
7196
    this.isMultiLine = function() {
 
7197
        return (this.start.row !== this.end.row);
 
7198
    };
 
7199
    this.clone = function() {
 
7200
        return Range.fromPoints(this.start, this.end);
 
7201
    };
 
7202
    this.collapseRows = function() {
 
7203
        if (this.end.column == 0)
 
7204
            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
 
7205
        else
 
7206
            return new Range(this.start.row, 0, this.end.row, 0)
 
7207
    };
 
7208
    this.toScreenRange = function(session) {
 
7209
        var screenPosStart = session.documentToScreenPosition(this.start);
 
7210
        var screenPosEnd = session.documentToScreenPosition(this.end);
 
7211
 
 
7212
        return new Range(
 
7213
            screenPosStart.row, screenPosStart.column,
 
7214
            screenPosEnd.row, screenPosEnd.column
 
7215
        );
 
7216
    };
 
7217
    this.moveBy = function(row, column) {
 
7218
        this.start.row += row;
 
7219
        this.start.column += column;
 
7220
        this.end.row += row;
 
7221
        this.end.column += column;
 
7222
    };
 
7223
 
 
7224
}).call(Range.prototype);
 
7225
Range.fromPoints = function(start, end) {
 
7226
    return new Range(start.row, start.column, end.row, end.column);
 
7227
};
 
7228
Range.comparePoints = comparePoints;
 
7229
 
 
7230
exports.Range = Range;
 
7231
});
 
7232
 
 
7233
define('ace/mode/text', ['require', 'exports', 'module' , 'ace/tokenizer', 'ace/mode/text_highlight_rules', 'ace/mode/behaviour', 'ace/unicode', 'ace/lib/lang'], function(require, exports, module) {
 
7234
 
 
7235
 
 
7236
var Tokenizer = require("../tokenizer").Tokenizer;
 
7237
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
 
7238
var Behaviour = require("./behaviour").Behaviour;
 
7239
var unicode = require("../unicode");
 
7240
var lang = require("../lib/lang");
 
7241
 
 
7242
var Mode = function() {
 
7243
    this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules());
 
7244
    this.$behaviour = new Behaviour();
 
7245
};
 
7246
 
 
7247
(function() {
 
7248
 
 
7249
    this.tokenRe = new RegExp("^["
 
7250
        + unicode.packages.L
 
7251
        + unicode.packages.Mn + unicode.packages.Mc
 
7252
        + unicode.packages.Nd
 
7253
        + unicode.packages.Pc + "\\$_]+", "g"
 
7254
    );
 
7255
    
 
7256
    this.nonTokenRe = new RegExp("^(?:[^"
 
7257
        + unicode.packages.L
 
7258
        + unicode.packages.Mn + unicode.packages.Mc
 
7259
        + unicode.packages.Nd
 
7260
        + unicode.packages.Pc + "\\$_]|\s])+", "g"
 
7261
    );
 
7262
 
 
7263
    this.getTokenizer = function() {
 
7264
        return this.$tokenizer;
 
7265
    };
 
7266
 
 
7267
    this.toggleCommentLines = function(state, session, startRow, endRow) {
 
7268
        var doc = session.doc;
 
7269
        var regexpStart, lineCommentStart;
 
7270
        if (!this.lineCommentStart) {
 
7271
            return false
 
7272
        } else if (Array.isArray(this.lineCommentStart)) {
 
7273
            regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|");
 
7274
            lineCommentStart = this.lineCommentStart[0];
 
7275
        } else {
 
7276
            regexpStart = lang.escapeRegExp(this.lineCommentStart);
 
7277
            lineCommentStart = this.lineCommentStart;
 
7278
        }
 
7279
        regexpStart = new RegExp("^\\s*(?:" + regexpStart + ") ?");
 
7280
 
 
7281
        var removeComment = true;
 
7282
        var minSpace = Infinity;
 
7283
        var indentations = [];
 
7284
 
 
7285
        for (var i = startRow; i <= endRow; i++) {
 
7286
            var line = doc.getLine(i);
 
7287
            var indent = line.search(/\S|$/);
 
7288
            indentations[i] = indent;
 
7289
            if (indent < minSpace)
 
7290
                minSpace = indent;
 
7291
            if (removeComment && !regexpStart.test(line))
 
7292
                removeComment = false;
 
7293
        }
 
7294
 
 
7295
        if (removeComment) {
 
7296
            for (var i = startRow; i <= endRow; i++) {
 
7297
                var line = doc.getLine(i);
 
7298
                var m = line.match(regexpStart);
 
7299
                doc.removeInLine(i, indentations[i], m[0].length);
 
7300
            }
 
7301
        } else {
 
7302
            lineCommentStart += " ";
 
7303
            for (var i = startRow; i <= endRow; i++) {
 
7304
                doc.insertInLine({row: i, column: minSpace}, lineCommentStart);
 
7305
            }
 
7306
        }
 
7307
    };
 
7308
 
 
7309
    this.getNextLineIndent = function(state, line, tab) {
 
7310
        return this.$getIndent(line);
 
7311
    };
 
7312
 
 
7313
    this.checkOutdent = function(state, line, input) {
 
7314
        return false;
 
7315
    };
 
7316
 
 
7317
    this.autoOutdent = function(state, doc, row) {
 
7318
    };
 
7319
 
 
7320
    this.$getIndent = function(line) {
 
7321
        return line.match(/^\s*/)[0];
 
7322
    };
 
7323
    
 
7324
    this.createWorker = function(session) {
 
7325
        return null;
 
7326
    };
 
7327
 
 
7328
    this.createModeDelegates = function (mapping) {
 
7329
        if (!this.$embeds) {
 
7330
            return;
 
7331
        }
 
7332
        this.$modes = {};
 
7333
        for (var i = 0; i < this.$embeds.length; i++) {
 
7334
            if (mapping[this.$embeds[i]]) {
 
7335
                this.$modes[this.$embeds[i]] = new mapping[this.$embeds[i]]();
 
7336
            }
 
7337
        }
 
7338
        
 
7339
        var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction'];
 
7340
 
 
7341
        for (var i = 0; i < delegations.length; i++) {
 
7342
            (function(scope) {
 
7343
              var functionName = delegations[i];
 
7344
              var defaultHandler = scope[functionName];
 
7345
              scope[delegations[i]] = function() {
 
7346
                  return this.$delegator(functionName, arguments, defaultHandler);
 
7347
              }
 
7348
            } (this));
 
7349
        }
 
7350
    }
 
7351
    
 
7352
    this.$delegator = function(method, args, defaultHandler) {
 
7353
        var state = args[0];
 
7354
        
 
7355
        for (var i = 0; i < this.$embeds.length; i++) {
 
7356
            if (!this.$modes[this.$embeds[i]]) continue;
 
7357
            
 
7358
            var split = state.split(this.$embeds[i]);
 
7359
            if (!split[0] && split[1]) {
 
7360
                args[0] = split[1];
 
7361
                var mode = this.$modes[this.$embeds[i]];
 
7362
                return mode[method].apply(mode, args);
 
7363
            }
 
7364
        }
 
7365
        var ret = defaultHandler.apply(this, args);
 
7366
        return defaultHandler ? ret : undefined;
 
7367
    };
 
7368
    
 
7369
    this.transformAction = function(state, action, editor, session, param) {
 
7370
        if (this.$behaviour) {
 
7371
            var behaviours = this.$behaviour.getBehaviours();
 
7372
            for (var key in behaviours) {
 
7373
                if (behaviours[key][action]) {
 
7374
                    var ret = behaviours[key][action].apply(this, arguments);
 
7375
                    if (ret) {
 
7376
                        return ret;
 
7377
                    }
 
7378
                }
 
7379
            }
 
7380
        }
 
7381
    }
 
7382
    
 
7383
}).call(Mode.prototype);
 
7384
 
 
7385
exports.Mode = Mode;
 
7386
});
 
7387
 
 
7388
define('ace/tokenizer', ['require', 'exports', 'module' ], function(require, exports, module) {
 
7389
var MAX_TOKEN_COUNT = 1000;
 
7390
var Tokenizer = function(rules) {
 
7391
    this.states = rules;
 
7392
 
 
7393
    this.regExps = {};
 
7394
    this.matchMappings = {};
 
7395
    for (var key in this.states) {
 
7396
        var state = this.states[key];
 
7397
        var ruleRegExps = [];
 
7398
        var matchTotal = 0;
 
7399
        var mapping = this.matchMappings[key] = {defaultToken: "text"};
 
7400
        var flag = "g";
 
7401
 
 
7402
        for (var i = 0; i < state.length; i++) {
 
7403
            var rule = state[i];
 
7404
            if (rule.defaultToken)
 
7405
                mapping.defaultToken = rule.defaultToken;
 
7406
            if (rule.caseInsensitive)
 
7407
                flag = "gi";
 
7408
            if (rule.regex == null)
 
7409
                continue;
 
7410
            
 
7411
            if (rule.regex instanceof RegExp)
 
7412
                rule.regex = rule.regex.toString().slice(1, -1);
 
7413
            var adjustedregex = rule.regex;
 
7414
            var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2;
 
7415
            if (Array.isArray(rule.token)) {
 
7416
                if (rule.token.length == 1) {
 
7417
                    rule.token = rule.token[0];
 
7418
                } else {
 
7419
                    rule.tokenArray = rule.token;
 
7420
                    rule.onMatch = this.$arrayTokens;
 
7421
                }
 
7422
            } else if (typeof rule.token == "function" && !rule.onMatch) {
 
7423
                if (matchcount > 1)
 
7424
                    rule.onMatch = this.$applyToken;
 
7425
                else
 
7426
                    rule.onMatch = rule.token;
 
7427
            }
 
7428
            
 
7429
            if (matchcount > 1) {
 
7430
                if (/\\\d/.test(rule.regex)) {
 
7431
                    adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function (match, digit) {
 
7432
                        return "\\" + (parseInt(digit, 10) + matchTotal + 1);
 
7433
                    });
 
7434
                } else {
 
7435
                    matchcount = 1;
 
7436
                    adjustedregex = this.removeCapturingGroups(rule.regex);
 
7437
                }
 
7438
                if (!rule.splitRegex && typeof rule.token != "string")
 
7439
                    rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
 
7440
            }
 
7441
 
 
7442
            mapping[matchTotal] = i;
 
7443
            matchTotal += matchcount;
 
7444
 
 
7445
            ruleRegExps.push(adjustedregex);
 
7446
            if (!rule.onMatch)
 
7447
                rule.onMatch = null;
 
7448
            rule.__proto__ = null;
 
7449
        }
 
7450
 
 
7451
        this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag);
 
7452
    }
 
7453
};
 
7454
 
 
7455
(function() {
 
7456
    this.$applyToken = function(str) {
 
7457
        var values = this.splitRegex.exec(str).slice(1);
 
7458
        var types = this.token.apply(this, values);
 
7459
        if (typeof types === "string")
 
7460
            return [{type: types, value: str}];
 
7461
 
 
7462
        var tokens = [];
 
7463
        for (var i = 0, l = types.length; i < l; i++) {
 
7464
            if (values[i])
 
7465
                tokens[tokens.length] = {
 
7466
                    type: types[i],
 
7467
                    value: values[i]
 
7468
                };
 
7469
        }
 
7470
        return tokens;
 
7471
    },
 
7472
 
 
7473
    this.$arrayTokens = function(str) {
 
7474
        if (!str)
 
7475
            return [];
 
7476
        var values = this.splitRegex.exec(str);
 
7477
        var tokens = [];
 
7478
        var types = this.tokenArray;
 
7479
        if (types.length != values.length - 1) {
 
7480
            if (window.console)
 
7481
                console.error(types , values, str, this.splitRegex, this);
 
7482
            return [{type: "error.invalid", value: str}];
 
7483
        }
 
7484
        for (var i = 0, l = types.length; i < l; i++) {
 
7485
            if (values[i + 1])
 
7486
                tokens[tokens.length] = {
 
7487
                    type: types[i],
 
7488
                    value: values[i + 1]
 
7489
                };
 
7490
        }
 
7491
        return tokens;
 
7492
    };
 
7493
    
 
7494
    this.removeCapturingGroups = function(src) {
 
7495
        var r = src.replace(
 
7496
            /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,
 
7497
            function(x, y) {return y ? "(?:" : x;}
 
7498
        );
 
7499
        return r;
 
7500
    };
 
7501
    
 
7502
    this.createSplitterRegexp = function(src, flag) {
 
7503
        if (src.indexOf("(?=") != -1) {
 
7504
            var stack = 0;
 
7505
            var inChClass = false;
 
7506
            var lastCapture = {};
 
7507
            src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([])/g, function(
 
7508
                m, esc, parenOpen, parenClose, square, index
 
7509
            ) {
 
7510
                if (inChClass) {
 
7511
                    inChClass = square != "]";
 
7512
                } else if (square) {
 
7513
                    inChClass = true;
 
7514
                } else if (parenClose) {
 
7515
                    if (stack == lastCapture.stack)
 
7516
                        lastCapture.end = index+1
 
7517
                    stack--;
 
7518
                } else if (parenOpen) {
 
7519
                    stack++;
 
7520
                    if (parenOpen.length != 1) {
 
7521
                        lastCapture.stack = stack
 
7522
                        lastCapture.start = index;
 
7523
                    }
 
7524
                }
 
7525
                return m;
 
7526
            });
 
7527
 
 
7528
            if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end)))
 
7529
                src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);
 
7530
        }
 
7531
        return new RegExp(src, (flag||"").replace("g", ""));
 
7532
    };
 
7533
    this.getLineTokens = function(line, startState) {
 
7534
        if (startState && typeof startState != "string") {
 
7535
            var stack = startState.slice(0);
 
7536
            startState = stack[0];
 
7537
        } else
 
7538
            var stack = [];
 
7539
 
 
7540
        var currentState = startState || "start";
 
7541
        var state = this.states[currentState];
 
7542
        var mapping = this.matchMappings[currentState];
 
7543
        var re = this.regExps[currentState];
 
7544
        re.lastIndex = 0;
 
7545
 
 
7546
        var match, tokens = [];
 
7547
        var lastIndex = 0;
 
7548
 
 
7549
        var token = {type: null, value: ""};
 
7550
 
 
7551
        while (match = re.exec(line)) {
 
7552
            var type = mapping.defaultToken;
 
7553
            var rule = null;
 
7554
            var value = match[0];
 
7555
            var index = re.lastIndex;
 
7556
 
 
7557
            if (index - value.length > lastIndex) {
 
7558
                var skipped = line.substring(lastIndex, index - value.length);
 
7559
                if (token.type == type) {
 
7560
                    token.value += skipped;
 
7561
                } else {
 
7562
                    if (token.type)
 
7563
                        tokens.push(token);
 
7564
                    token = {type: type, value: skipped};
 
7565
                }
 
7566
            }
 
7567
 
 
7568
            for (var i = 0; i < match.length-2; i++) {
 
7569
                if (match[i + 1] === undefined)
 
7570
                    continue;
 
7571
 
 
7572
                rule = state[mapping[i]];
 
7573
 
 
7574
                if (rule.onMatch)
 
7575
                    type = rule.onMatch(value, currentState, stack);
 
7576
                else
 
7577
                    type = rule.token;
 
7578
 
 
7579
                if (rule.next) {
 
7580
                    if (typeof rule.next == "string")
 
7581
                        currentState = rule.next;
 
7582
                    else
 
7583
                        currentState = rule.next(currentState, stack);
 
7584
 
 
7585
                    state = this.states[currentState];
 
7586
                    if (!state) {
 
7587
                        window.console && console.error && console.error(currentState, "doesn't exist");
 
7588
                        currentState = "start";
 
7589
                        state = this.states[currentState];
 
7590
                    }
 
7591
                    mapping = this.matchMappings[currentState];
 
7592
                    lastIndex = index;
 
7593
                    re = this.regExps[currentState];
 
7594
                    re.lastIndex = index;
 
7595
                }
 
7596
                break;
 
7597
            }
 
7598
 
 
7599
            if (value) {
 
7600
                if (typeof type == "string") {
 
7601
                    if ((!rule || rule.merge !== false) && token.type === type) {
 
7602
                        token.value += value;
 
7603
                    } else {
 
7604
                        if (token.type)
 
7605
                            tokens.push(token);
 
7606
                        token = {type: type, value: value};
 
7607
                    }
 
7608
                } else {
 
7609
                    if (token.type)
 
7610
                        tokens.push(token);
 
7611
                    token = {type: null, value: ""};
 
7612
                    for (var i = 0; i < type.length; i++)
 
7613
                        tokens.push(type[i]);
 
7614
                }
 
7615
            }
 
7616
 
 
7617
            if (lastIndex == line.length)
 
7618
                break;
 
7619
 
 
7620
            lastIndex = index;
 
7621
 
 
7622
            if (tokens.length > MAX_TOKEN_COUNT) {
 
7623
                token.value += line.substr(lastIndex);
 
7624
                currentState = "start"
 
7625
                break;
 
7626
            }
 
7627
        }
 
7628
 
 
7629
        if (token.type)
 
7630
            tokens.push(token);
 
7631
 
 
7632
        return {
 
7633
            tokens : tokens,
 
7634
            state : stack.length ? stack : currentState
 
7635
        };
 
7636
    };
 
7637
 
 
7638
}).call(Tokenizer.prototype);
 
7639
 
 
7640
exports.Tokenizer = Tokenizer;
 
7641
});
 
7642
 
 
7643
define('ace/mode/text_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/lang'], function(require, exports, module) {
 
7644
 
 
7645
 
 
7646
var lang = require("../lib/lang");
 
7647
 
 
7648
var TextHighlightRules = function() {
 
7649
 
 
7650
    this.$rules = {
 
7651
        "start" : [{
 
7652
            token : "empty_line",
 
7653
            regex : '^$'
 
7654
        }, {
 
7655
            defaultToken : "text"
 
7656
        }]
 
7657
    };
 
7658
};
 
7659
 
 
7660
(function() {
 
7661
 
 
7662
    this.addRules = function(rules, prefix) {
 
7663
        for (var key in rules) {
 
7664
            var state = rules[key];
 
7665
            for (var i = 0; i < state.length; i++) {
 
7666
                var rule = state[i];
 
7667
                if (rule.next) {
 
7668
                    rule.next = prefix + rule.next;
 
7669
                }
 
7670
            }
 
7671
            this.$rules[prefix + key] = state;
 
7672
        }
 
7673
    };
 
7674
 
 
7675
    this.getRules = function() {
 
7676
        return this.$rules;
 
7677
    };
 
7678
 
 
7679
    this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {
 
7680
        var embedRules = new HighlightRules().getRules();
 
7681
        if (states) {
 
7682
            for (var i = 0; i < states.length; i++)
 
7683
                states[i] = prefix + states[i];
 
7684
        } else {
 
7685
            states = [];
 
7686
            for (var key in embedRules)
 
7687
                states.push(prefix + key);
 
7688
        }
 
7689
 
 
7690
        this.addRules(embedRules, prefix);
 
7691
 
 
7692
        if (escapeRules) {
 
7693
            var addRules = Array.prototype[append ? "push" : "unshift"];
 
7694
            for (var i = 0; i < states.length; i++)
 
7695
                addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));
 
7696
        }
 
7697
 
 
7698
        if (!this.$embeds)
 
7699
            this.$embeds = [];
 
7700
        this.$embeds.push(prefix);
 
7701
    }
 
7702
 
 
7703
    this.getEmbeds = function() {
 
7704
        return this.$embeds;
 
7705
    };
 
7706
 
 
7707
    var pushState = function(currentState, stack) {
 
7708
        if (currentState != "start")
 
7709
            stack.unshift(this.nextState, currentState);
 
7710
        return this.nextState;
 
7711
    };
 
7712
    var popState = function(currentState, stack) {
 
7713
        if (stack[0] !== currentState)
 
7714
            return "start";
 
7715
        stack.shift();
 
7716
        return stack.shift();
 
7717
    };
 
7718
 
 
7719
    this.normalizeRules = function() {
 
7720
        var id = 0;
 
7721
        var rules = this.$rules;
 
7722
        function processState(key) {
 
7723
            var state = rules[key];
 
7724
            state.processed = true;
 
7725
            for (var i = 0; i < state.length; i++) {
 
7726
                var rule = state[i];
 
7727
                if (!rule.regex && rule.start) {
 
7728
                    rule.regex = rule.start;
 
7729
                    if (!rule.next)
 
7730
                        rule.next = [];
 
7731
                    rule.next.push({
 
7732
                        defaultToken: rule.token
 
7733
                    }, {
 
7734
                        token: rule.token + ".end",
 
7735
                        regex: rule.end || rule.start,
 
7736
                        next: "pop"
 
7737
                    });
 
7738
                    rule.token = rule.token + ".start";
 
7739
                    rule.push = true;
 
7740
                }
 
7741
                var next = rule.next || rule.push;
 
7742
                if (next && Array.isArray(next)) {
 
7743
                    var stateName = rule.stateName || (rule.token + id++);
 
7744
                    rules[stateName] = next;
 
7745
                    rule.next = stateName;
 
7746
                    processState(stateName);
 
7747
                } else if (next == "pop") {
 
7748
                    rule.next = popState;
 
7749
                }
 
7750
 
 
7751
                if (rule.push) {
 
7752
                    rule.nextState = rule.next || rule.push;
 
7753
                    rule.next = pushState;
 
7754
                    delete rule.push;
 
7755
                }
 
7756
 
 
7757
                if (rule.rules) {
 
7758
                    for (var r in rule.rules) {
 
7759
                        if (rules[r]) {
 
7760
                            if (rules[r].push)
 
7761
                                rules[r].push.apply(rules[r], rule.rules[r]);
 
7762
                        } else {
 
7763
                            rules[r] = rule.rules[r];
 
7764
                        }
 
7765
                    }
 
7766
                }
 
7767
                if (rule.include || typeof rule == "string") {
 
7768
                    var includeName = rule.include || rule;
 
7769
                    var toInsert = rules[includeName];
 
7770
                } else if (Array.isArray(rule))
 
7771
                    toInsert = rule;
 
7772
 
 
7773
                if (toInsert) {
 
7774
                    var args = [i, 1].concat(toInsert);
 
7775
                    if (rule.noEscape)
 
7776
                        args = args.filter(function(x) {return !x.next;});
 
7777
                    state.splice.apply(state, args);
 
7778
                    i--;
 
7779
                    toInsert = null
 
7780
                }
 
7781
            }
 
7782
        };
 
7783
        Object.keys(rules).forEach(processState);
 
7784
    };
 
7785
 
 
7786
    this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {
 
7787
        var keywords = Object.create(null);
 
7788
        Object.keys(map).forEach(function(className) {
 
7789
            var a = map[className];
 
7790
            if (ignoreCase)
 
7791
                a = a.toLowerCase();
 
7792
            var list = a.split(splitChar || "|");
 
7793
            for (var i = list.length; i--; )
 
7794
                keywords[list[i]] = className;
 
7795
        });
 
7796
        map = null;
 
7797
        return ignoreCase
 
7798
            ? function(value) {return keywords[value.toLowerCase()] || defaultToken }
 
7799
            : function(value) {return keywords[value] || defaultToken };
 
7800
    }
 
7801
 
 
7802
    this.getKeywords = function() {
 
7803
        return this.$keywords;
 
7804
    };
 
7805
 
 
7806
}).call(TextHighlightRules.prototype);
 
7807
 
 
7808
exports.TextHighlightRules = TextHighlightRules;
 
7809
});
 
7810
 
 
7811
define('ace/mode/behaviour', ['require', 'exports', 'module' ], function(require, exports, module) {
 
7812
 
 
7813
 
 
7814
var Behaviour = function() {
 
7815
   this.$behaviours = {};
 
7816
};
 
7817
 
 
7818
(function () {
 
7819
 
 
7820
    this.add = function (name, action, callback) {
 
7821
        switch (undefined) {
 
7822
          case this.$behaviours:
 
7823
              this.$behaviours = {};
 
7824
          case this.$behaviours[name]:
 
7825
              this.$behaviours[name] = {};
 
7826
        }
 
7827
        this.$behaviours[name][action] = callback;
 
7828
    }
 
7829
    
 
7830
    this.addBehaviours = function (behaviours) {
 
7831
        for (var key in behaviours) {
 
7832
            for (var action in behaviours[key]) {
 
7833
                this.add(key, action, behaviours[key][action]);
 
7834
            }
 
7835
        }
 
7836
    }
 
7837
    
 
7838
    this.remove = function (name) {
 
7839
        if (this.$behaviours && this.$behaviours[name]) {
 
7840
            delete this.$behaviours[name];
 
7841
        }
 
7842
    }
 
7843
    
 
7844
    this.inherit = function (mode, filter) {
 
7845
        if (typeof mode === "function") {
 
7846
            var behaviours = new mode().getBehaviours(filter);
 
7847
        } else {
 
7848
            var behaviours = mode.getBehaviours(filter);
 
7849
        }
 
7850
        this.addBehaviours(behaviours);
 
7851
    }
 
7852
    
 
7853
    this.getBehaviours = function (filter) {
 
7854
        if (!filter) {
 
7855
            return this.$behaviours;
 
7856
        } else {
 
7857
            var ret = {}
 
7858
            for (var i = 0; i < filter.length; i++) {
 
7859
                if (this.$behaviours[filter[i]]) {
 
7860
                    ret[filter[i]] = this.$behaviours[filter[i]];
 
7861
                }
 
7862
            }
 
7863
            return ret;
 
7864
        }
 
7865
    }
 
7866
 
 
7867
}).call(Behaviour.prototype);
 
7868
 
 
7869
exports.Behaviour = Behaviour;
 
7870
});
 
7871
define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) {
 
7872
exports.packages = {};
 
7873
 
 
7874
addUnicodePackage({
 
7875
    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",
 
7876
    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",
 
7877
    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",
 
7878
    Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",
 
7879
    Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",
 
7880
    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",
 
7881
    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",
 
7882
    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",
 
7883
    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",
 
7884
    Me: "0488048906DE20DD-20E020E2-20E4A670-A672",
 
7885
    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",
 
7886
    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",
 
7887
    Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",
 
7888
    No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",
 
7889
    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",
 
7890
    Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",
 
7891
    Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",
 
7892
    Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",
 
7893
    Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",
 
7894
    Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21",
 
7895
    Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F",
 
7896
    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",
 
7897
    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",
 
7898
    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",
 
7899
    Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",
 
7900
    Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",
 
7901
    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",
 
7902
    Z:  "002000A01680180E2000-200A20282029202F205F3000",
 
7903
    Zs: "002000A01680180E2000-200A202F205F3000",
 
7904
    Zl: "2028",
 
7905
    Zp: "2029",
 
7906
    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",
 
7907
    Cc: "0000-001F007F-009F",
 
7908
    Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",
 
7909
    Co: "E000-F8FF",
 
7910
    Cs: "D800-DFFF",
 
7911
    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"
 
7912
});
 
7913
 
 
7914
function addUnicodePackage (pack) {
 
7915
    var codePoint = /\w{4}/g;
 
7916
    for (var name in pack)
 
7917
        exports.packages[name] = pack[name].replace(codePoint, "\\u$&");
 
7918
};
 
7919
 
 
7920
});
 
7921
 
 
7922
define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
 
7923
 
 
7924
 
 
7925
var oop = require("./lib/oop");
 
7926
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
7927
var Range = require("./range").Range;
 
7928
var Anchor = require("./anchor").Anchor;
 
7929
 
 
7930
var Document = function(text) {
 
7931
    this.$lines = [];
 
7932
    if (text.length == 0) {
 
7933
        this.$lines = [""];
 
7934
    } else if (Array.isArray(text)) {
 
7935
        this.insertLines(0, text);
 
7936
    } else {
 
7937
        this.insert({row: 0, column:0}, text);
 
7938
    }
 
7939
};
 
7940
 
 
7941
(function() {
 
7942
 
 
7943
    oop.implement(this, EventEmitter);
 
7944
    this.setValue = function(text) {
 
7945
        var len = this.getLength();
 
7946
        this.remove(new Range(0, 0, len, this.getLine(len-1).length));
 
7947
        this.insert({row: 0, column:0}, text);
 
7948
    };
 
7949
    this.getValue = function() {
 
7950
        return this.getAllLines().join(this.getNewLineCharacter());
 
7951
    };
 
7952
    this.createAnchor = function(row, column) {
 
7953
        return new Anchor(this, row, column);
 
7954
    };
 
7955
    if ("aaa".split(/a/).length == 0)
 
7956
        this.$split = function(text) {
 
7957
            return text.replace(/\r\n|\r/g, "\n").split("\n");
 
7958
        }
 
7959
    else
 
7960
        this.$split = function(text) {
 
7961
            return text.split(/\r\n|\r|\n/);
 
7962
        };
 
7963
 
 
7964
 
 
7965
 
 
7966
    this.$detectNewLine = function(text) {
 
7967
        var match = text.match(/^.*?(\r\n|\r|\n)/m);
 
7968
        if (match) {
 
7969
            this.$autoNewLine = match[1];
 
7970
        } else {
 
7971
            this.$autoNewLine = "\n";
 
7972
        }
 
7973
    };
 
7974
    this.getNewLineCharacter = function() {
 
7975
        switch (this.$newLineMode) {
 
7976
          case "windows":
 
7977
            return "\r\n";
 
7978
 
 
7979
          case "unix":
 
7980
            return "\n";
 
7981
 
 
7982
          default:
 
7983
            return this.$autoNewLine;
 
7984
        }
 
7985
    };
 
7986
 
 
7987
    this.$autoNewLine = "\n";
 
7988
    this.$newLineMode = "auto";
 
7989
    this.setNewLineMode = function(newLineMode) {
 
7990
        if (this.$newLineMode === newLineMode)
 
7991
            return;
 
7992
 
 
7993
        this.$newLineMode = newLineMode;
 
7994
    };
 
7995
    this.getNewLineMode = function() {
 
7996
        return this.$newLineMode;
 
7997
    };
 
7998
    this.isNewLine = function(text) {
 
7999
        return (text == "\r\n" || text == "\r" || text == "\n");
 
8000
    };
 
8001
    this.getLine = function(row) {
 
8002
        return this.$lines[row] || "";
 
8003
    };
 
8004
    this.getLines = function(firstRow, lastRow) {
 
8005
        return this.$lines.slice(firstRow, lastRow + 1);
 
8006
    };
 
8007
    this.getAllLines = function() {
 
8008
        return this.getLines(0, this.getLength());
 
8009
    };
 
8010
    this.getLength = function() {
 
8011
        return this.$lines.length;
 
8012
    };
 
8013
    this.getTextRange = function(range) {
 
8014
        if (range.start.row == range.end.row) {
 
8015
            return this.$lines[range.start.row].substring(range.start.column,
 
8016
                                                         range.end.column);
 
8017
        }
 
8018
        else {
 
8019
            var lines = this.getLines(range.start.row+1, range.end.row-1);
 
8020
            lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
 
8021
            lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
 
8022
            return lines.join(this.getNewLineCharacter());
 
8023
        }
 
8024
    };
 
8025
 
 
8026
    this.$clipPosition = function(position) {
 
8027
        var length = this.getLength();
 
8028
        if (position.row >= length) {
 
8029
            position.row = Math.max(0, length - 1);
 
8030
            position.column = this.getLine(length-1).length;
 
8031
        }
 
8032
        return position;
 
8033
    };
 
8034
    this.insert = function(position, text) {
 
8035
        if (!text || text.length === 0)
 
8036
            return position;
 
8037
 
 
8038
        position = this.$clipPosition(position);
 
8039
        if (this.getLength() <= 1)
 
8040
            this.$detectNewLine(text);
 
8041
 
 
8042
        var lines = this.$split(text);
 
8043
        var firstLine = lines.splice(0, 1)[0];
 
8044
        var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
 
8045
 
 
8046
        position = this.insertInLine(position, firstLine);
 
8047
        if (lastLine !== null) {
 
8048
            position = this.insertNewLine(position); // terminate first line
 
8049
            position = this.insertLines(position.row, lines);
 
8050
            position = this.insertInLine(position, lastLine || "");
 
8051
        }
 
8052
        return position;
 
8053
    };
 
8054
    this.insertLines = function(row, lines) {
 
8055
        if (lines.length == 0)
 
8056
            return {row: row, column: 0};
 
8057
        if (lines.length > 0xFFFF) {
 
8058
            var end = this.insertLines(row, lines.slice(0xFFFF));
 
8059
            lines = lines.slice(0, 0xFFFF);
 
8060
        }
 
8061
 
 
8062
        var args = [row, 0];
 
8063
        args.push.apply(args, lines);
 
8064
        this.$lines.splice.apply(this.$lines, args);
 
8065
 
 
8066
        var range = new Range(row, 0, row + lines.length, 0);
 
8067
        var delta = {
 
8068
            action: "insertLines",
 
8069
            range: range,
 
8070
            lines: lines
 
8071
        };
 
8072
        this._emit("change", { data: delta });
 
8073
        return end || range.end;
 
8074
    };
 
8075
    this.insertNewLine = function(position) {
 
8076
        position = this.$clipPosition(position);
 
8077
        var line = this.$lines[position.row] || "";
 
8078
 
 
8079
        this.$lines[position.row] = line.substring(0, position.column);
 
8080
        this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
 
8081
 
 
8082
        var end = {
 
8083
            row : position.row + 1,
 
8084
            column : 0
 
8085
        };
 
8086
 
 
8087
        var delta = {
 
8088
            action: "insertText",
 
8089
            range: Range.fromPoints(position, end),
 
8090
            text: this.getNewLineCharacter()
 
8091
        };
 
8092
        this._emit("change", { data: delta });
 
8093
 
 
8094
        return end;
 
8095
    };
 
8096
    this.insertInLine = function(position, text) {
 
8097
        if (text.length == 0)
 
8098
            return position;
 
8099
 
 
8100
        var line = this.$lines[position.row] || "";
 
8101
 
 
8102
        this.$lines[position.row] = line.substring(0, position.column) + text
 
8103
                + line.substring(position.column);
 
8104
 
 
8105
        var end = {
 
8106
            row : position.row,
 
8107
            column : position.column + text.length
 
8108
        };
 
8109
 
 
8110
        var delta = {
 
8111
            action: "insertText",
 
8112
            range: Range.fromPoints(position, end),
 
8113
            text: text
 
8114
        };
 
8115
        this._emit("change", { data: delta });
 
8116
 
 
8117
        return end;
 
8118
    };
 
8119
    this.remove = function(range) {
 
8120
        range.start = this.$clipPosition(range.start);
 
8121
        range.end = this.$clipPosition(range.end);
 
8122
 
 
8123
        if (range.isEmpty())
 
8124
            return range.start;
 
8125
 
 
8126
        var firstRow = range.start.row;
 
8127
        var lastRow = range.end.row;
 
8128
 
 
8129
        if (range.isMultiLine()) {
 
8130
            var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
 
8131
            var lastFullRow = lastRow - 1;
 
8132
 
 
8133
            if (range.end.column > 0)
 
8134
                this.removeInLine(lastRow, 0, range.end.column);
 
8135
 
 
8136
            if (lastFullRow >= firstFullRow)
 
8137
                this.removeLines(firstFullRow, lastFullRow);
 
8138
 
 
8139
            if (firstFullRow != firstRow) {
 
8140
                this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
 
8141
                this.removeNewLine(range.start.row);
 
8142
            }
 
8143
        }
 
8144
        else {
 
8145
            this.removeInLine(firstRow, range.start.column, range.end.column);
 
8146
        }
 
8147
        return range.start;
 
8148
    };
 
8149
    this.removeInLine = function(row, startColumn, endColumn) {
 
8150
        if (startColumn == endColumn)
 
8151
            return;
 
8152
 
 
8153
        var range = new Range(row, startColumn, row, endColumn);
 
8154
        var line = this.getLine(row);
 
8155
        var removed = line.substring(startColumn, endColumn);
 
8156
        var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
 
8157
        this.$lines.splice(row, 1, newLine);
 
8158
 
 
8159
        var delta = {
 
8160
            action: "removeText",
 
8161
            range: range,
 
8162
            text: removed
 
8163
        };
 
8164
        this._emit("change", { data: delta });
 
8165
        return range.start;
 
8166
    };
 
8167
    this.removeLines = function(firstRow, lastRow) {
 
8168
        var range = new Range(firstRow, 0, lastRow + 1, 0);
 
8169
        var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
 
8170
 
 
8171
        var delta = {
 
8172
            action: "removeLines",
 
8173
            range: range,
 
8174
            nl: this.getNewLineCharacter(),
 
8175
            lines: removed
 
8176
        };
 
8177
        this._emit("change", { data: delta });
 
8178
        return removed;
 
8179
    };
 
8180
    this.removeNewLine = function(row) {
 
8181
        var firstLine = this.getLine(row);
 
8182
        var secondLine = this.getLine(row+1);
 
8183
 
 
8184
        var range = new Range(row, firstLine.length, row+1, 0);
 
8185
        var line = firstLine + secondLine;
 
8186
 
 
8187
        this.$lines.splice(row, 2, line);
 
8188
 
 
8189
        var delta = {
 
8190
            action: "removeText",
 
8191
            range: range,
 
8192
            text: this.getNewLineCharacter()
 
8193
        };
 
8194
        this._emit("change", { data: delta });
 
8195
    };
 
8196
    this.replace = function(range, text) {
 
8197
        if (text.length == 0 && range.isEmpty())
 
8198
            return range.start;
 
8199
        if (text == this.getTextRange(range))
 
8200
            return range.end;
 
8201
 
 
8202
        this.remove(range);
 
8203
        if (text) {
 
8204
            var end = this.insert(range.start, text);
 
8205
        }
 
8206
        else {
 
8207
            end = range.start;
 
8208
        }
 
8209
 
 
8210
        return end;
 
8211
    };
 
8212
    this.applyDeltas = function(deltas) {
 
8213
        for (var i=0; i<deltas.length; i++) {
 
8214
            var delta = deltas[i];
 
8215
            var range = Range.fromPoints(delta.range.start, delta.range.end);
 
8216
 
 
8217
            if (delta.action == "insertLines")
 
8218
                this.insertLines(range.start.row, delta.lines);
 
8219
            else if (delta.action == "insertText")
 
8220
                this.insert(range.start, delta.text);
 
8221
            else if (delta.action == "removeLines")
 
8222
                this.removeLines(range.start.row, range.end.row - 1);
 
8223
            else if (delta.action == "removeText")
 
8224
                this.remove(range);
 
8225
        }
 
8226
    };
 
8227
    this.revertDeltas = function(deltas) {
 
8228
        for (var i=deltas.length-1; i>=0; i--) {
 
8229
            var delta = deltas[i];
 
8230
 
 
8231
            var range = Range.fromPoints(delta.range.start, delta.range.end);
 
8232
 
 
8233
            if (delta.action == "insertLines")
 
8234
                this.removeLines(range.start.row, range.end.row - 1);
 
8235
            else if (delta.action == "insertText")
 
8236
                this.remove(range);
 
8237
            else if (delta.action == "removeLines")
 
8238
                this.insertLines(range.start.row, delta.lines);
 
8239
            else if (delta.action == "removeText")
 
8240
                this.insert(range.start, delta.text);
 
8241
        }
 
8242
    };
 
8243
    this.indexToPosition = function(index, startRow) {
 
8244
        var lines = this.$lines || this.getAllLines();
 
8245
        var newlineLength = this.getNewLineCharacter().length;
 
8246
        for (var i = startRow || 0, l = lines.length; i < l; i++) {
 
8247
            index -= lines[i].length + newlineLength;
 
8248
            if (index < 0)
 
8249
                return {row: i, column: index + lines[i].length + newlineLength};
 
8250
        }
 
8251
        return {row: l-1, column: lines[l-1].length};
 
8252
    };
 
8253
    this.positionToIndex = function(pos, startRow) {
 
8254
        var lines = this.$lines || this.getAllLines();
 
8255
        var newlineLength = this.getNewLineCharacter().length;
 
8256
        var index = 0;
 
8257
        var row = Math.min(pos.row, lines.length);
 
8258
        for (var i = startRow || 0; i < row; ++i)
 
8259
            index += lines[i].length;
 
8260
 
 
8261
        return index + newlineLength * i + pos.column;
 
8262
    };
 
8263
 
 
8264
}).call(Document.prototype);
 
8265
 
 
8266
exports.Document = Document;
 
8267
});
 
8268
 
 
8269
define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
 
8270
 
 
8271
 
 
8272
var oop = require("./lib/oop");
 
8273
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
8274
 
 
8275
var Anchor = exports.Anchor = function(doc, row, column) {
 
8276
    this.document = doc;
 
8277
    
 
8278
    if (typeof column == "undefined")
 
8279
        this.setPosition(row.row, row.column);
 
8280
    else
 
8281
        this.setPosition(row, column);
 
8282
 
 
8283
    this.$onChange = this.onChange.bind(this);
 
8284
    doc.on("change", this.$onChange);
 
8285
};
 
8286
 
 
8287
(function() {
 
8288
 
 
8289
    oop.implement(this, EventEmitter);
 
8290
 
 
8291
    this.getPosition = function() {
 
8292
        return this.$clipPositionToDocument(this.row, this.column);
 
8293
    };
 
8294
        
 
8295
    this.getDocument = function() {
 
8296
        return this.document;
 
8297
    };
 
8298
 
 
8299
    this.onChange = function(e) {
 
8300
        var delta = e.data;
 
8301
        var range = delta.range;
 
8302
            
 
8303
        if (range.start.row == range.end.row && range.start.row != this.row)
 
8304
            return;
 
8305
            
 
8306
        if (range.start.row > this.row)
 
8307
            return;
 
8308
            
 
8309
        if (range.start.row == this.row && range.start.column > this.column)
 
8310
            return;
 
8311
    
 
8312
        var row = this.row;
 
8313
        var column = this.column;
 
8314
        
 
8315
        if (delta.action === "insertText") {
 
8316
            if (range.start.row === row && range.start.column <= column) {
 
8317
                if (range.start.row === range.end.row) {
 
8318
                    column += range.end.column - range.start.column;
 
8319
                }
 
8320
                else {
 
8321
                    column -= range.start.column;
 
8322
                    row += range.end.row - range.start.row;
 
8323
                }
 
8324
            }
 
8325
            else if (range.start.row !== range.end.row && range.start.row < row) {
 
8326
                row += range.end.row - range.start.row;
 
8327
            }
 
8328
        } else if (delta.action === "insertLines") {
 
8329
            if (range.start.row <= row) {
 
8330
                row += range.end.row - range.start.row;
 
8331
            }
 
8332
        }
 
8333
        else if (delta.action == "removeText") {
 
8334
            if (range.start.row == row && range.start.column < column) {
 
8335
                if (range.end.column >= column)
 
8336
                    column = range.start.column;
 
8337
                else
 
8338
                    column = Math.max(0, column - (range.end.column - range.start.column));
 
8339
                
 
8340
            } else if (range.start.row !== range.end.row && range.start.row < row) {
 
8341
                if (range.end.row == row) {
 
8342
                    column = Math.max(0, column - range.end.column) + range.start.column;
 
8343
                }
 
8344
                row -= (range.end.row - range.start.row);
 
8345
            }
 
8346
            else if (range.end.row == row) {
 
8347
                row -= range.end.row - range.start.row;
 
8348
                column = Math.max(0, column - range.end.column) + range.start.column;
 
8349
            }
 
8350
        } else if (delta.action == "removeLines") {
 
8351
            if (range.start.row <= row) {
 
8352
                if (range.end.row <= row)
 
8353
                    row -= range.end.row - range.start.row;
 
8354
                else {
 
8355
                    row = range.start.row;
 
8356
                    column = 0;
 
8357
                }
 
8358
            }
 
8359
        }
 
8360
 
 
8361
        this.setPosition(row, column, true);
 
8362
    };
 
8363
 
 
8364
    this.setPosition = function(row, column, noClip) {
 
8365
        var pos;
 
8366
        if (noClip) {
 
8367
            pos = {
 
8368
                row: row,
 
8369
                column: column
 
8370
            };
 
8371
        }
 
8372
        else {
 
8373
            pos = this.$clipPositionToDocument(row, column);
 
8374
        }
 
8375
        
 
8376
        if (this.row == pos.row && this.column == pos.column)
 
8377
            return;
 
8378
            
 
8379
        var old = {
 
8380
            row: this.row,
 
8381
            column: this.column
 
8382
        };
 
8383
        
 
8384
        this.row = pos.row;
 
8385
        this.column = pos.column;
 
8386
        this._emit("change", {
 
8387
            old: old,
 
8388
            value: pos
 
8389
        });
 
8390
    };
 
8391
 
 
8392
    this.detach = function() {
 
8393
        this.document.removeEventListener("change", this.$onChange);
 
8394
    };
 
8395
    this.$clipPositionToDocument = function(row, column) {
 
8396
        var pos = {};
 
8397
    
 
8398
        if (row >= this.document.getLength()) {
 
8399
            pos.row = Math.max(0, this.document.getLength() - 1);
 
8400
            pos.column = this.document.getLine(pos.row).length;
 
8401
        }
 
8402
        else if (row < 0) {
 
8403
            pos.row = 0;
 
8404
            pos.column = 0;
 
8405
        }
 
8406
        else {
 
8407
            pos.row = row;
 
8408
            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
 
8409
        }
 
8410
        
 
8411
        if (column < 0)
 
8412
            pos.column = 0;
 
8413
            
 
8414
        return pos;
 
8415
    };
 
8416
    
 
8417
}).call(Anchor.prototype);
 
8418
 
 
8419
});
 
8420
 
 
8421
define('ace/background_tokenizer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
 
8422
 
 
8423
 
 
8424
var oop = require("./lib/oop");
 
8425
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
8426
 
 
8427
var BackgroundTokenizer = function(tokenizer, editor) {
 
8428
    this.running = false;
 
8429
    this.lines = [];
 
8430
    this.states = [];
 
8431
    this.currentLine = 0;
 
8432
    this.tokenizer = tokenizer;
 
8433
 
 
8434
    var self = this;
 
8435
 
 
8436
    this.$worker = function() {
 
8437
        if (!self.running) { return; }
 
8438
 
 
8439
        var workerStart = new Date();
 
8440
        var startLine = self.currentLine;
 
8441
        var doc = self.doc;
 
8442
 
 
8443
        var processedLines = 0;
 
8444
 
 
8445
        var len = doc.getLength();
 
8446
        while (self.currentLine < len) {
 
8447
            self.$tokenizeRow(self.currentLine);
 
8448
            while (self.lines[self.currentLine])
 
8449
                self.currentLine++;
 
8450
            processedLines ++;
 
8451
            if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
 
8452
                self.fireUpdateEvent(startLine, self.currentLine-1);
 
8453
                self.running = setTimeout(self.$worker, 20);
 
8454
                return;
 
8455
            }
 
8456
        }
 
8457
 
 
8458
        self.running = false;
 
8459
 
 
8460
        self.fireUpdateEvent(startLine, len - 1);
 
8461
    };
 
8462
};
 
8463
 
 
8464
(function(){
 
8465
 
 
8466
    oop.implement(this, EventEmitter);
 
8467
    this.setTokenizer = function(tokenizer) {
 
8468
        this.tokenizer = tokenizer;
 
8469
        this.lines = [];
 
8470
        this.states = [];
 
8471
 
 
8472
        this.start(0);
 
8473
    };
 
8474
    this.setDocument = function(doc) {
 
8475
        this.doc = doc;
 
8476
        this.lines = [];
 
8477
        this.states = [];
 
8478
 
 
8479
        this.stop();
 
8480
    };
 
8481
    this.fireUpdateEvent = function(firstRow, lastRow) {
 
8482
        var data = {
 
8483
            first: firstRow,
 
8484
            last: lastRow
 
8485
        };
 
8486
        this._emit("update", {data: data});
 
8487
    };
 
8488
    this.start = function(startRow) {
 
8489
        this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
 
8490
        this.lines.splice(this.currentLine, this.lines.length);
 
8491
        this.states.splice(this.currentLine, this.states.length);
 
8492
 
 
8493
        this.stop();
 
8494
        this.running = setTimeout(this.$worker, 700);
 
8495
    };
 
8496
 
 
8497
    this.$updateOnChange = function(delta) {
 
8498
        var range = delta.range;
 
8499
        var startRow = range.start.row;
 
8500
        var len = range.end.row - startRow;
 
8501
 
 
8502
        if (len === 0) {
 
8503
            this.lines[startRow] = null;
 
8504
        } else if (delta.action == "removeText" || delta.action == "removeLines") {
 
8505
            this.lines.splice(startRow, len + 1, null);
 
8506
            this.states.splice(startRow, len + 1, null);
 
8507
        } else {
 
8508
            var args = Array(len + 1);
 
8509
            args.unshift(startRow, 1);
 
8510
            this.lines.splice.apply(this.lines, args);
 
8511
            this.states.splice.apply(this.states, args);
 
8512
        }
 
8513
 
 
8514
        this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
 
8515
 
 
8516
        this.stop();
 
8517
        this.running = setTimeout(this.$worker, 700);
 
8518
    };
 
8519
    this.stop = function() {
 
8520
        if (this.running)
 
8521
            clearTimeout(this.running);
 
8522
        this.running = false;
 
8523
    };
 
8524
    this.getTokens = function(row) {
 
8525
        return this.lines[row] || this.$tokenizeRow(row);
 
8526
    };
 
8527
    this.getState = function(row) {
 
8528
        if (this.currentLine == row)
 
8529
            this.$tokenizeRow(row);
 
8530
        return this.states[row] || "start";
 
8531
    };
 
8532
 
 
8533
    this.$tokenizeRow = function(row) {
 
8534
        var line = this.doc.getLine(row);
 
8535
        var state = this.states[row - 1];
 
8536
 
 
8537
        var data = this.tokenizer.getLineTokens(line, state, row);
 
8538
 
 
8539
        if (this.states[row] + "" !== data.state + "") {
 
8540
            this.states[row] = data.state;
 
8541
            this.lines[row + 1] = null;
 
8542
            if (this.currentLine > row + 1)
 
8543
                this.currentLine = row + 1;
 
8544
        } else if (this.currentLine == row) {
 
8545
            this.currentLine = row + 1;
 
8546
        }
 
8547
 
 
8548
        return this.lines[row] = data.tokens;
 
8549
    };
 
8550
 
 
8551
}).call(BackgroundTokenizer.prototype);
 
8552
 
 
8553
exports.BackgroundTokenizer = BackgroundTokenizer;
 
8554
});
 
8555
 
 
8556
define('ace/search_highlight', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
 
8557
 
 
8558
 
 
8559
var lang = require("./lib/lang");
 
8560
var oop = require("./lib/oop");
 
8561
var Range = require("./range").Range;
 
8562
 
 
8563
var SearchHighlight = function(regExp, clazz, type) {
 
8564
    this.setRegexp(regExp);
 
8565
    this.clazz = clazz;
 
8566
    this.type = type || "text";
 
8567
};
 
8568
 
 
8569
(function() {
 
8570
    this.MAX_RANGES = 500;
 
8571
    
 
8572
    this.setRegexp = function(regExp) {
 
8573
        if (this.regExp+"" == regExp+"")
 
8574
            return;
 
8575
        this.regExp = regExp;
 
8576
        this.cache = [];
 
8577
    };
 
8578
 
 
8579
    this.update = function(html, markerLayer, session, config) {
 
8580
        if (!this.regExp)
 
8581
            return;
 
8582
        var start = config.firstRow, end = config.lastRow;
 
8583
 
 
8584
        for (var i = start; i <= end; i++) {
 
8585
            var ranges = this.cache[i];
 
8586
            if (ranges == null) {
 
8587
                ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);
 
8588
                if (ranges.length > this.MAX_RANGES)
 
8589
                    ranges = ranges.slice(0, this.MAX_RANGES);
 
8590
                ranges = ranges.map(function(match) {
 
8591
                    return new Range(i, match.offset, i, match.offset + match.length);
 
8592
                });
 
8593
                this.cache[i] = ranges.length ? ranges : "";
 
8594
            }
 
8595
 
 
8596
            for (var j = ranges.length; j --; ) {
 
8597
                markerLayer.drawSingleLineMarker(
 
8598
                    html, ranges[j].toScreenRange(session), this.clazz, config,
 
8599
                    null, this.type
 
8600
                );
 
8601
            }
 
8602
        }
 
8603
    };
 
8604
 
 
8605
}).call(SearchHighlight.prototype);
 
8606
 
 
8607
exports.SearchHighlight = SearchHighlight;
 
8608
});
 
8609
 
 
8610
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) {
 
8611
 
 
8612
 
 
8613
var Range = require("../range").Range;
 
8614
var FoldLine = require("./fold_line").FoldLine;
 
8615
var Fold = require("./fold").Fold;
 
8616
var TokenIterator = require("../token_iterator").TokenIterator;
 
8617
 
 
8618
function Folding() {
 
8619
    this.getFoldAt = function(row, column, side) {
 
8620
        var foldLine = this.getFoldLine(row);
 
8621
        if (!foldLine)
 
8622
            return null;
 
8623
 
 
8624
        var folds = foldLine.folds;
 
8625
        for (var i = 0; i < folds.length; i++) {
 
8626
            var fold = folds[i];
 
8627
            if (fold.range.contains(row, column)) {
 
8628
                if (side == 1 && fold.range.isEnd(row, column)) {
 
8629
                    continue;
 
8630
                } else if (side == -1 && fold.range.isStart(row, column)) {
 
8631
                    continue;
 
8632
                }
 
8633
                return fold;
 
8634
            }
 
8635
        }
 
8636
    };
 
8637
    this.getFoldsInRange = function(range) {
 
8638
        var start = range.start;
 
8639
        var end = range.end;
 
8640
        var foldLines = this.$foldData;
 
8641
        var foundFolds = [];
 
8642
 
 
8643
        start.column += 1;
 
8644
        end.column -= 1;
 
8645
 
 
8646
        for (var i = 0; i < foldLines.length; i++) {
 
8647
            var cmp = foldLines[i].range.compareRange(range);
 
8648
            if (cmp == 2) {
 
8649
                continue;
 
8650
            }
 
8651
            else if (cmp == -2) {
 
8652
                break;
 
8653
            }
 
8654
 
 
8655
            var folds = foldLines[i].folds;
 
8656
            for (var j = 0; j < folds.length; j++) {
 
8657
                var fold = folds[j];
 
8658
                cmp = fold.range.compareRange(range);
 
8659
                if (cmp == -2) {
 
8660
                    break;
 
8661
                } else if (cmp == 2) {
 
8662
                    continue;
 
8663
                } else
 
8664
                if (cmp == 42) {
 
8665
                    break;
 
8666
                }
 
8667
                foundFolds.push(fold);
 
8668
            }
 
8669
        }
 
8670
        start.column -= 1;
 
8671
        end.column += 1;
 
8672
 
 
8673
        return foundFolds;
 
8674
    };
 
8675
    this.getAllFolds = function() {
 
8676
        var folds = [];
 
8677
        var foldLines = this.$foldData;
 
8678
        
 
8679
        function addFold(fold) {
 
8680
            folds.push(fold);
 
8681
        }
 
8682
        
 
8683
        for (var i = 0; i < foldLines.length; i++)
 
8684
            for (var j = 0; j < foldLines[i].folds.length; j++)
 
8685
                addFold(foldLines[i].folds[j]);
 
8686
 
 
8687
        return folds;
 
8688
    };
 
8689
    this.getFoldStringAt = function(row, column, trim, foldLine) {
 
8690
        foldLine = foldLine || this.getFoldLine(row);
 
8691
        if (!foldLine)
 
8692
            return null;
 
8693
 
 
8694
        var lastFold = {
 
8695
            end: { column: 0 }
 
8696
        };
 
8697
        var str, fold;
 
8698
        for (var i = 0; i < foldLine.folds.length; i++) {
 
8699
            fold = foldLine.folds[i];
 
8700
            var cmp = fold.range.compareEnd(row, column);
 
8701
            if (cmp == -1) {
 
8702
                str = this
 
8703
                    .getLine(fold.start.row)
 
8704
                    .substring(lastFold.end.column, fold.start.column);
 
8705
                break;
 
8706
            }
 
8707
            else if (cmp === 0) {
 
8708
                return null;
 
8709
            }
 
8710
            lastFold = fold;
 
8711
        }
 
8712
        if (!str)
 
8713
            str = this.getLine(fold.start.row).substring(lastFold.end.column);
 
8714
 
 
8715
        if (trim == -1)
 
8716
            return str.substring(0, column - lastFold.end.column);
 
8717
        else if (trim == 1)
 
8718
            return str.substring(column - lastFold.end.column);
 
8719
        else
 
8720
            return str;
 
8721
    };
 
8722
 
 
8723
    this.getFoldLine = function(docRow, startFoldLine) {
 
8724
        var foldData = this.$foldData;
 
8725
        var i = 0;
 
8726
        if (startFoldLine)
 
8727
            i = foldData.indexOf(startFoldLine);
 
8728
        if (i == -1)
 
8729
            i = 0;
 
8730
        for (i; i < foldData.length; i++) {
 
8731
            var foldLine = foldData[i];
 
8732
            if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
 
8733
                return foldLine;
 
8734
            } else if (foldLine.end.row > docRow) {
 
8735
                return null;
 
8736
            }
 
8737
        }
 
8738
        return null;
 
8739
    };
 
8740
    this.getNextFoldLine = function(docRow, startFoldLine) {
 
8741
        var foldData = this.$foldData;
 
8742
        var i = 0;
 
8743
        if (startFoldLine)
 
8744
            i = foldData.indexOf(startFoldLine);
 
8745
        if (i == -1)
 
8746
            i = 0;
 
8747
        for (i; i < foldData.length; i++) {
 
8748
            var foldLine = foldData[i];
 
8749
            if (foldLine.end.row >= docRow) {
 
8750
                return foldLine;
 
8751
            }
 
8752
        }
 
8753
        return null;
 
8754
    };
 
8755
 
 
8756
    this.getFoldedRowCount = function(first, last) {
 
8757
        var foldData = this.$foldData, rowCount = last-first+1;
 
8758
        for (var i = 0; i < foldData.length; i++) {
 
8759
            var foldLine = foldData[i],
 
8760
                end = foldLine.end.row,
 
8761
                start = foldLine.start.row;
 
8762
            if (end >= last) {
 
8763
                if(start < last) {
 
8764
                    if(start >= first)
 
8765
                        rowCount -= last-start;
 
8766
                    else
 
8767
                        rowCount = 0;//in one fold
 
8768
                }
 
8769
                break;
 
8770
            } else if(end >= first){
 
8771
                if (start >= first) //fold inside range
 
8772
                    rowCount -=  end-start;
 
8773
                else
 
8774
                    rowCount -=  end-first+1;
 
8775
            }
 
8776
        }
 
8777
        return rowCount;
 
8778
    };
 
8779
 
 
8780
    this.$addFoldLine = function(foldLine) {
 
8781
        this.$foldData.push(foldLine);
 
8782
        this.$foldData.sort(function(a, b) {
 
8783
            return a.start.row - b.start.row;
 
8784
        });
 
8785
        return foldLine;
 
8786
    };
 
8787
    this.addFold = function(placeholder, range) {
 
8788
        var foldData = this.$foldData;
 
8789
        var added = false;
 
8790
        var fold;
 
8791
        
 
8792
        if (placeholder instanceof Fold)
 
8793
            fold = placeholder;
 
8794
        else {
 
8795
            fold = new Fold(range, placeholder);
 
8796
            fold.collapseChildren = range.collapseChildren;
 
8797
        }
 
8798
        this.$clipRangeToDocument(fold.range);
 
8799
 
 
8800
        var startRow = fold.start.row;
 
8801
        var startColumn = fold.start.column;
 
8802
        var endRow = fold.end.row;
 
8803
        var endColumn = fold.end.column;
 
8804
        if (startRow == endRow && endColumn - startColumn < 2)
 
8805
            throw "The range has to be at least 2 characters width";
 
8806
 
 
8807
        var startFold = this.getFoldAt(startRow, startColumn, 1);
 
8808
        var endFold = this.getFoldAt(endRow, endColumn, -1);
 
8809
        if (startFold && endFold == startFold)
 
8810
            return startFold.addSubFold(fold);
 
8811
 
 
8812
        if (
 
8813
            (startFold && !startFold.range.isStart(startRow, startColumn))
 
8814
            || (endFold && !endFold.range.isEnd(endRow, endColumn))
 
8815
        ) {
 
8816
            throw "A fold can't intersect already existing fold" + fold.range + startFold.range;
 
8817
        }
 
8818
        var folds = this.getFoldsInRange(fold.range);
 
8819
        if (folds.length > 0) {
 
8820
            this.removeFolds(folds);
 
8821
            folds.forEach(function(subFold) {
 
8822
                fold.addSubFold(subFold);
 
8823
            });
 
8824
        }
 
8825
 
 
8826
        for (var i = 0; i < foldData.length; i++) {
 
8827
            var foldLine = foldData[i];
 
8828
            if (endRow == foldLine.start.row) {
 
8829
                foldLine.addFold(fold);
 
8830
                added = true;
 
8831
                break;
 
8832
            } else if (startRow == foldLine.end.row) {
 
8833
                foldLine.addFold(fold);
 
8834
                added = true;
 
8835
                if (!fold.sameRow) {
 
8836
                    var foldLineNext = foldData[i + 1];
 
8837
                    if (foldLineNext && foldLineNext.start.row == endRow) {
 
8838
                        foldLine.merge(foldLineNext);
 
8839
                        break;
 
8840
                    }
 
8841
                }
 
8842
                break;
 
8843
            } else if (endRow <= foldLine.start.row) {
 
8844
                break;
 
8845
            }
 
8846
        }
 
8847
 
 
8848
        if (!added)
 
8849
            foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
 
8850
 
 
8851
        if (this.$useWrapMode)
 
8852
            this.$updateWrapData(foldLine.start.row, foldLine.start.row);
 
8853
        else
 
8854
            this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);
 
8855
        this.$modified = true;
 
8856
        this._emit("changeFold", { data: fold });
 
8857
 
 
8858
        return fold;
 
8859
    };
 
8860
 
 
8861
    this.addFolds = function(folds) {
 
8862
        folds.forEach(function(fold) {
 
8863
            this.addFold(fold);
 
8864
        }, this);
 
8865
    };
 
8866
 
 
8867
    this.removeFold = function(fold) {
 
8868
        var foldLine = fold.foldLine;
 
8869
        var startRow = foldLine.start.row;
 
8870
        var endRow = foldLine.end.row;
 
8871
 
 
8872
        var foldLines = this.$foldData;
 
8873
        var folds = foldLine.folds;
 
8874
        if (folds.length == 1) {
 
8875
            foldLines.splice(foldLines.indexOf(foldLine), 1);
 
8876
        } else
 
8877
        if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {
 
8878
            folds.pop();
 
8879
            foldLine.end.row = folds[folds.length - 1].end.row;
 
8880
            foldLine.end.column = folds[folds.length - 1].end.column;
 
8881
        } else
 
8882
        if (foldLine.range.isStart(fold.start.row, fold.start.column)) {
 
8883
            folds.shift();
 
8884
            foldLine.start.row = folds[0].start.row;
 
8885
            foldLine.start.column = folds[0].start.column;
 
8886
        } else
 
8887
        if (fold.sameRow) {
 
8888
            folds.splice(folds.indexOf(fold), 1);
 
8889
        } else
 
8890
        {
 
8891
            var newFoldLine = foldLine.split(fold.start.row, fold.start.column);
 
8892
            folds = newFoldLine.folds;
 
8893
            folds.shift();
 
8894
            newFoldLine.start.row = folds[0].start.row;
 
8895
            newFoldLine.start.column = folds[0].start.column;
 
8896
        }
 
8897
 
 
8898
        if (this.$useWrapMode)
 
8899
            this.$updateWrapData(startRow, endRow);
 
8900
        else
 
8901
            this.$updateRowLengthCache(startRow, endRow);
 
8902
        this.$modified = true;
 
8903
        this._emit("changeFold", { data: fold });
 
8904
    };
 
8905
 
 
8906
    this.removeFolds = function(folds) {
 
8907
        var cloneFolds = [];
 
8908
        for (var i = 0; i < folds.length; i++) {
 
8909
            cloneFolds.push(folds[i]);
 
8910
        }
 
8911
 
 
8912
        cloneFolds.forEach(function(fold) {
 
8913
            this.removeFold(fold);
 
8914
        }, this);
 
8915
        this.$modified = true;
 
8916
    };
 
8917
 
 
8918
    this.expandFold = function(fold) {
 
8919
        this.removeFold(fold);        
 
8920
        fold.subFolds.forEach(function(subFold) {
 
8921
            fold.restoreRange(subFold);
 
8922
            this.addFold(subFold);
 
8923
        }, this);
 
8924
        if (fold.collapseChildren > 0) {
 
8925
            this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
 
8926
        }
 
8927
        fold.subFolds = [];
 
8928
    };
 
8929
 
 
8930
    this.expandFolds = function(folds) {
 
8931
        folds.forEach(function(fold) {
 
8932
            this.expandFold(fold);
 
8933
        }, this);
 
8934
    };
 
8935
 
 
8936
    this.unfold = function(location, expandInner) {
 
8937
        var range, folds;
 
8938
        if (location == null) {
 
8939
            range = new Range(0, 0, this.getLength(), 0);
 
8940
            expandInner = true;
 
8941
        } else if (typeof location == "number")
 
8942
            range = new Range(location, 0, location, this.getLine(location).length);
 
8943
        else if ("row" in location)
 
8944
            range = Range.fromPoints(location, location);
 
8945
        else
 
8946
            range = location;
 
8947
 
 
8948
        folds = this.getFoldsInRange(range);
 
8949
        if (expandInner) {
 
8950
            this.removeFolds(folds);
 
8951
        } else {
 
8952
            while (folds.length) {
 
8953
                this.expandFolds(folds);
 
8954
                folds = this.getFoldsInRange(range);
 
8955
            }
 
8956
        }
 
8957
    };
 
8958
    this.isRowFolded = function(docRow, startFoldRow) {
 
8959
        return !!this.getFoldLine(docRow, startFoldRow);
 
8960
    };
 
8961
 
 
8962
    this.getRowFoldEnd = function(docRow, startFoldRow) {
 
8963
        var foldLine = this.getFoldLine(docRow, startFoldRow);
 
8964
        return foldLine ? foldLine.end.row : docRow;
 
8965
    };
 
8966
 
 
8967
    this.getRowFoldStart = function(docRow, startFoldRow) {
 
8968
        var foldLine = this.getFoldLine(docRow, startFoldRow);
 
8969
        return foldLine ? foldLine.start.row : docRow;
 
8970
    };
 
8971
 
 
8972
    this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
 
8973
        if (startRow == null) {
 
8974
            startRow = foldLine.start.row;
 
8975
            startColumn = 0;
 
8976
        }
 
8977
 
 
8978
        if (endRow == null) {
 
8979
            endRow = foldLine.end.row;
 
8980
            endColumn = this.getLine(endRow).length;
 
8981
        }
 
8982
        var doc = this.doc;
 
8983
        var textLine = "";
 
8984
 
 
8985
        foldLine.walk(function(placeholder, row, column, lastColumn) {
 
8986
            if (row < startRow)
 
8987
                return;
 
8988
            if (row == startRow) {
 
8989
                if (column < startColumn)
 
8990
                    return;
 
8991
                lastColumn = Math.max(startColumn, lastColumn);
 
8992
            }
 
8993
 
 
8994
            if (placeholder != null) {
 
8995
                textLine += placeholder;
 
8996
            } else {
 
8997
                textLine += doc.getLine(row).substring(lastColumn, column);
 
8998
            }
 
8999
        }, endRow, endColumn);
 
9000
        return textLine;
 
9001
    };
 
9002
 
 
9003
    this.getDisplayLine = function(row, endColumn, startRow, startColumn) {
 
9004
        var foldLine = this.getFoldLine(row);
 
9005
 
 
9006
        if (!foldLine) {
 
9007
            var line;
 
9008
            line = this.doc.getLine(row);
 
9009
            return line.substring(startColumn || 0, endColumn || line.length);
 
9010
        } else {
 
9011
            return this.getFoldDisplayLine(
 
9012
                foldLine, row, endColumn, startRow, startColumn);
 
9013
        }
 
9014
    };
 
9015
 
 
9016
    this.$cloneFoldData = function() {
 
9017
        var fd = [];
 
9018
        fd = this.$foldData.map(function(foldLine) {
 
9019
            var folds = foldLine.folds.map(function(fold) {
 
9020
                return fold.clone();
 
9021
            });
 
9022
            return new FoldLine(fd, folds);
 
9023
        });
 
9024
 
 
9025
        return fd;
 
9026
    };
 
9027
 
 
9028
    this.toggleFold = function(tryToUnfold) {
 
9029
        var selection = this.selection;
 
9030
        var range = selection.getRange();
 
9031
        var fold;
 
9032
        var bracketPos;
 
9033
 
 
9034
        if (range.isEmpty()) {
 
9035
            var cursor = range.start;
 
9036
            fold = this.getFoldAt(cursor.row, cursor.column);
 
9037
 
 
9038
            if (fold) {
 
9039
                this.expandFold(fold);
 
9040
                return;
 
9041
            } else if (bracketPos = this.findMatchingBracket(cursor)) {
 
9042
                if (range.comparePoint(bracketPos) == 1) {
 
9043
                    range.end = bracketPos;
 
9044
                } else {
 
9045
                    range.start = bracketPos;
 
9046
                    range.start.column++;
 
9047
                    range.end.column--;
 
9048
                }
 
9049
            } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
 
9050
                if (range.comparePoint(bracketPos) == 1)
 
9051
                    range.end = bracketPos;
 
9052
                else
 
9053
                    range.start = bracketPos;
 
9054
 
 
9055
                range.start.column++;
 
9056
            } else {
 
9057
                range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
 
9058
            }
 
9059
        } else {
 
9060
            var folds = this.getFoldsInRange(range);
 
9061
            if (tryToUnfold && folds.length) {
 
9062
                this.expandFolds(folds);
 
9063
                return;
 
9064
            } else if (folds.length == 1 ) {
 
9065
                fold = folds[0];
 
9066
            }
 
9067
        }
 
9068
 
 
9069
        if (!fold)
 
9070
            fold = this.getFoldAt(range.start.row, range.start.column);
 
9071
 
 
9072
        if (fold && fold.range.toString() == range.toString()) {
 
9073
            this.expandFold(fold);
 
9074
            return;
 
9075
        }
 
9076
 
 
9077
        var placeholder = "...";
 
9078
        if (!range.isMultiLine()) {
 
9079
            placeholder = this.getTextRange(range);
 
9080
            if(placeholder.length < 4)
 
9081
                return;
 
9082
            placeholder = placeholder.trim().substring(0, 2) + "..";
 
9083
        }
 
9084
 
 
9085
        this.addFold(placeholder, range);
 
9086
    };
 
9087
 
 
9088
    this.getCommentFoldRange = function(row, column, dir) {
 
9089
        var iterator = new TokenIterator(this, row, column);
 
9090
        var token = iterator.getCurrentToken();
 
9091
        if (token && /^comment|string/.test(token.type)) {
 
9092
            var range = new Range();
 
9093
            var re = new RegExp(token.type.replace(/\..*/, "\\."));
 
9094
            if (dir != 1) {
 
9095
                do {
 
9096
                    token = iterator.stepBackward();
 
9097
                } while(token && re.test(token.type));
 
9098
                iterator.stepForward();
 
9099
            }
 
9100
            
 
9101
            range.start.row = iterator.getCurrentTokenRow();
 
9102
            range.start.column = iterator.getCurrentTokenColumn() + 2;
 
9103
 
 
9104
            iterator = new TokenIterator(this, row, column);
 
9105
            
 
9106
            if (dir != -1) {
 
9107
                do {
 
9108
                    token = iterator.stepForward();
 
9109
                } while(token && re.test(token.type));
 
9110
                token = iterator.stepBackward();
 
9111
            } else
 
9112
                token = iterator.getCurrentToken();
 
9113
 
 
9114
            range.end.row = iterator.getCurrentTokenRow();
 
9115
            range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
 
9116
            return range;
 
9117
        }
 
9118
    };
 
9119
 
 
9120
    this.foldAll = function(startRow, endRow, depth) {
 
9121
        if (depth == undefined)
 
9122
            depth = 100000; // JSON.stringify doesn't hanle Infinity
 
9123
        var foldWidgets = this.foldWidgets;
 
9124
        endRow = endRow || this.getLength();
 
9125
        for (var row = startRow || 0; row < endRow; row++) {
 
9126
            if (foldWidgets[row] == null)
 
9127
                foldWidgets[row] = this.getFoldWidget(row);
 
9128
            if (foldWidgets[row] != "start")
 
9129
                continue;
 
9130
 
 
9131
            var range = this.getFoldWidgetRange(row);
 
9132
            if (range && range.end.row <= endRow) try {
 
9133
                var fold = this.addFold("...", range);
 
9134
                fold.collapseChildren = depth;
 
9135
            } catch(e) {}
 
9136
            row = range.end.row;
 
9137
        }
 
9138
    };
 
9139
    this.$foldStyles = {
 
9140
        "manual": 1,
 
9141
        "markbegin": 1,
 
9142
        "markbeginend": 1
 
9143
    };
 
9144
    this.$foldStyle = "markbegin";
 
9145
    this.setFoldStyle = function(style) {
 
9146
        if (!this.$foldStyles[style])
 
9147
            throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]");
 
9148
        
 
9149
        if (this.$foldStyle == style)
 
9150
            return;
 
9151
 
 
9152
        this.$foldStyle = style;
 
9153
        
 
9154
        if (style == "manual")
 
9155
            this.unfold();
 
9156
        var mode = this.$foldMode;
 
9157
        this.$setFolding(null);
 
9158
        this.$setFolding(mode);
 
9159
    };
 
9160
 
 
9161
    this.$setFolding = function(foldMode) {
 
9162
        if (this.$foldMode == foldMode)
 
9163
            return;
 
9164
            
 
9165
        this.$foldMode = foldMode;
 
9166
        
 
9167
        this.removeListener('change', this.$updateFoldWidgets);
 
9168
        this._emit("changeAnnotation");
 
9169
        
 
9170
        if (!foldMode || this.$foldStyle == "manual") {
 
9171
            this.foldWidgets = null;
 
9172
            return;
 
9173
        }
 
9174
        
 
9175
        this.foldWidgets = [];
 
9176
        this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);
 
9177
        this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);
 
9178
        
 
9179
        this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);
 
9180
        this.on('change', this.$updateFoldWidgets);
 
9181
        
 
9182
    };
 
9183
 
 
9184
    this.getParentFoldRangeData = function (row, ignoreCurrent) {
 
9185
        var fw = this.foldWidgets;
 
9186
        if (!fw || (ignoreCurrent && fw[row]))
 
9187
            return {};
 
9188
 
 
9189
        var i = row - 1, firstRange;
 
9190
        while (i >= 0) {
 
9191
            var c = fw[i];
 
9192
            if (c == null)
 
9193
                c = fw[i] = this.getFoldWidget(i);
 
9194
 
 
9195
            if (c == "start") {
 
9196
                var range = this.getFoldWidgetRange(i);
 
9197
                if (!firstRange)
 
9198
                    firstRange = range;
 
9199
                if (range && range.end.row >= row)
 
9200
                    break;
 
9201
            }
 
9202
            i--;
 
9203
        }
 
9204
 
 
9205
        return {
 
9206
            range: i !== -1 && range,
 
9207
            firstRange: firstRange
 
9208
        };
 
9209
    }
 
9210
 
 
9211
    this.onFoldWidgetClick = function(row, e) {
 
9212
        var type = this.getFoldWidget(row);
 
9213
        var line = this.getLine(row);
 
9214
        e = e.domEvent;
 
9215
        var children = e.shiftKey;
 
9216
        var all = e.ctrlKey || e.metaKey;
 
9217
        var siblings = e.altKey;
 
9218
 
 
9219
        var dir = type === "end" ? -1 : 1;
 
9220
        var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
 
9221
 
 
9222
        if (fold) {
 
9223
            if (children || all)
 
9224
                this.removeFold(fold);
 
9225
            else
 
9226
                this.expandFold(fold);
 
9227
            return;
 
9228
        }
 
9229
 
 
9230
        var range = this.getFoldWidgetRange(row);
 
9231
        if (range && !range.isMultiLine()) {
 
9232
            fold = this.getFoldAt(range.start.row, range.start.column, 1);
 
9233
            if (fold && range.isEqual(fold.range)) {
 
9234
                this.removeFold(fold);
 
9235
                return;
 
9236
            }
 
9237
        }
 
9238
        
 
9239
        if (siblings) {
 
9240
            var data = this.getParentFoldRangeData(row);
 
9241
            if (data.range) {
 
9242
                var startRow = data.range.start.row + 1;
 
9243
                var endRow = data.range.end.row;
 
9244
            }
 
9245
            this.foldAll(startRow, endRow, all ? 10000 : 0);
 
9246
        } else if (children) {
 
9247
            var endRow = range ? range.end.row : this.getLength();
 
9248
            this.foldAll(row + 1, range.end.row, all ? 10000 : 0);
 
9249
        } else if (range) {
 
9250
            if (all) 
 
9251
                range.collapseChildren = 10000;
 
9252
            this.addFold("...", range);
 
9253
        }
 
9254
        
 
9255
        if (!range)
 
9256
            (e.target || e.srcElement).className += " ace_invalid"
 
9257
    };
 
9258
 
 
9259
    this.updateFoldWidgets = function(e) {
 
9260
        var delta = e.data;
 
9261
        var range = delta.range;
 
9262
        var firstRow = range.start.row;
 
9263
        var len = range.end.row - firstRow;
 
9264
 
 
9265
        if (len === 0) {
 
9266
            this.foldWidgets[firstRow] = null;
 
9267
        } else if (delta.action == "removeText" || delta.action == "removeLines") {
 
9268
            this.foldWidgets.splice(firstRow, len + 1, null);
 
9269
        } else {
 
9270
            var args = Array(len + 1);
 
9271
            args.unshift(firstRow, 1);
 
9272
            this.foldWidgets.splice.apply(this.foldWidgets, args);
 
9273
        }
 
9274
    };
 
9275
 
 
9276
}
 
9277
 
 
9278
exports.Folding = Folding;
 
9279
 
 
9280
});
 
9281
 
 
9282
define('ace/edit_session/fold_line', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
 
9283
 
 
9284
 
 
9285
var Range = require("../range").Range;
 
9286
function FoldLine(foldData, folds) {
 
9287
    this.foldData = foldData;
 
9288
    if (Array.isArray(folds)) {
 
9289
        this.folds = folds;
 
9290
    } else {
 
9291
        folds = this.folds = [ folds ];
 
9292
    }
 
9293
 
 
9294
    var last = folds[folds.length - 1]
 
9295
    this.range = new Range(folds[0].start.row, folds[0].start.column,
 
9296
                           last.end.row, last.end.column);
 
9297
    this.start = this.range.start;
 
9298
    this.end   = this.range.end;
 
9299
 
 
9300
    this.folds.forEach(function(fold) {
 
9301
        fold.setFoldLine(this);
 
9302
    }, this);
 
9303
}
 
9304
 
 
9305
(function() {
 
9306
    this.shiftRow = function(shift) {
 
9307
        this.start.row += shift;
 
9308
        this.end.row += shift;
 
9309
        this.folds.forEach(function(fold) {
 
9310
            fold.start.row += shift;
 
9311
            fold.end.row += shift;
 
9312
        });
 
9313
    }
 
9314
 
 
9315
    this.addFold = function(fold) {
 
9316
        if (fold.sameRow) {
 
9317
            if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
 
9318
                throw "Can't add a fold to this FoldLine as it has no connection";
 
9319
            }
 
9320
            this.folds.push(fold);
 
9321
            this.folds.sort(function(a, b) {
 
9322
                return -a.range.compareEnd(b.start.row, b.start.column);
 
9323
            });
 
9324
            if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {
 
9325
                this.end.row = fold.end.row;
 
9326
                this.end.column =  fold.end.column;
 
9327
            } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {
 
9328
                this.start.row = fold.start.row;
 
9329
                this.start.column = fold.start.column;
 
9330
            }
 
9331
        } else if (fold.start.row == this.end.row) {
 
9332
            this.folds.push(fold);
 
9333
            this.end.row = fold.end.row;
 
9334
            this.end.column = fold.end.column;
 
9335
        } else if (fold.end.row == this.start.row) {
 
9336
            this.folds.unshift(fold);
 
9337
            this.start.row = fold.start.row;
 
9338
            this.start.column = fold.start.column;
 
9339
        } else {
 
9340
            throw "Trying to add fold to FoldRow that doesn't have a matching row";
 
9341
        }
 
9342
        fold.foldLine = this;
 
9343
    }
 
9344
 
 
9345
    this.containsRow = function(row) {
 
9346
        return row >= this.start.row && row <= this.end.row;
 
9347
    }
 
9348
 
 
9349
    this.walk = function(callback, endRow, endColumn) {
 
9350
        var lastEnd = 0,
 
9351
            folds = this.folds,
 
9352
            fold,
 
9353
            comp, stop, isNewRow = true;
 
9354
 
 
9355
        if (endRow == null) {
 
9356
            endRow = this.end.row;
 
9357
            endColumn = this.end.column;
 
9358
        }
 
9359
 
 
9360
        for (var i = 0; i < folds.length; i++) {
 
9361
            fold = folds[i];
 
9362
 
 
9363
            comp = fold.range.compareStart(endRow, endColumn);
 
9364
            if (comp == -1) {
 
9365
                callback(null, endRow, endColumn, lastEnd, isNewRow);
 
9366
                return;
 
9367
            }
 
9368
 
 
9369
            stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
 
9370
            stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
 
9371
            if (stop || comp == 0) {
 
9372
                return;
 
9373
            }
 
9374
            isNewRow = !fold.sameRow;
 
9375
            lastEnd = fold.end.column;
 
9376
        }
 
9377
        callback(null, endRow, endColumn, lastEnd, isNewRow);
 
9378
    }
 
9379
 
 
9380
    this.getNextFoldTo = function(row, column) {
 
9381
        var fold, cmp;
 
9382
        for (var i = 0; i < this.folds.length; i++) {
 
9383
            fold = this.folds[i];
 
9384
            cmp = fold.range.compareEnd(row, column);
 
9385
            if (cmp == -1) {
 
9386
                return {
 
9387
                    fold: fold,
 
9388
                    kind: "after"
 
9389
                };
 
9390
            } else if (cmp == 0) {
 
9391
                return {
 
9392
                    fold: fold,
 
9393
                    kind: "inside"
 
9394
                }
 
9395
            }
 
9396
        }
 
9397
        return null;
 
9398
    }
 
9399
 
 
9400
    this.addRemoveChars = function(row, column, len) {
 
9401
        var ret = this.getNextFoldTo(row, column),
 
9402
            fold, folds;
 
9403
        if (ret) {
 
9404
            fold = ret.fold;
 
9405
            if (ret.kind == "inside"
 
9406
                && fold.start.column != column
 
9407
                && fold.start.row != row)
 
9408
            {
 
9409
                window.console && window.console.log(row, column, fold);
 
9410
            } else if (fold.start.row == row) {
 
9411
                folds = this.folds;
 
9412
                var i = folds.indexOf(fold);
 
9413
                if (i == 0) {
 
9414
                    this.start.column += len;
 
9415
                }
 
9416
                for (i; i < folds.length; i++) {
 
9417
                    fold = folds[i];
 
9418
                    fold.start.column += len;
 
9419
                    if (!fold.sameRow) {
 
9420
                        return;
 
9421
                    }
 
9422
                    fold.end.column += len;
 
9423
                }
 
9424
                this.end.column += len;
 
9425
            }
 
9426
        }
 
9427
    }
 
9428
 
 
9429
    this.split = function(row, column) {
 
9430
        var fold = this.getNextFoldTo(row, column).fold;
 
9431
        var folds = this.folds;
 
9432
        var foldData = this.foldData;
 
9433
 
 
9434
        if (!fold)
 
9435
            return null;
 
9436
 
 
9437
        var i = folds.indexOf(fold);
 
9438
        var foldBefore = folds[i - 1];
 
9439
        this.end.row = foldBefore.end.row;
 
9440
        this.end.column = foldBefore.end.column;
 
9441
        folds = folds.splice(i, folds.length - i);
 
9442
 
 
9443
        var newFoldLine = new FoldLine(foldData, folds);
 
9444
        foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
 
9445
        return newFoldLine;
 
9446
    }
 
9447
 
 
9448
    this.merge = function(foldLineNext) {
 
9449
        var folds = foldLineNext.folds;
 
9450
        for (var i = 0; i < folds.length; i++) {
 
9451
            this.addFold(folds[i]);
 
9452
        }
 
9453
        var foldData = this.foldData;
 
9454
        foldData.splice(foldData.indexOf(foldLineNext), 1);
 
9455
    }
 
9456
 
 
9457
    this.toString = function() {
 
9458
        var ret = [this.range.toString() + ": [" ];
 
9459
 
 
9460
        this.folds.forEach(function(fold) {
 
9461
            ret.push("  " + fold.toString());
 
9462
        });
 
9463
        ret.push("]")
 
9464
        return ret.join("\n");
 
9465
    }
 
9466
 
 
9467
    this.idxToPosition = function(idx) {
 
9468
        var lastFoldEndColumn = 0;
 
9469
        var fold;
 
9470
 
 
9471
        for (var i = 0; i < this.folds.length; i++) {
 
9472
            var fold = this.folds[i];
 
9473
 
 
9474
            idx -= fold.start.column - lastFoldEndColumn;
 
9475
            if (idx < 0) {
 
9476
                return {
 
9477
                    row: fold.start.row,
 
9478
                    column: fold.start.column + idx
 
9479
                };
 
9480
            }
 
9481
 
 
9482
            idx -= fold.placeholder.length;
 
9483
            if (idx < 0) {
 
9484
                return fold.start;
 
9485
            }
 
9486
 
 
9487
            lastFoldEndColumn = fold.end.column;
 
9488
        }
 
9489
 
 
9490
        return {
 
9491
            row: this.end.row,
 
9492
            column: this.end.column + idx
 
9493
        };
 
9494
    }
 
9495
}).call(FoldLine.prototype);
 
9496
 
 
9497
exports.FoldLine = FoldLine;
 
9498
});
 
9499
 
 
9500
define('ace/edit_session/fold', ['require', 'exports', 'module' , 'ace/range', 'ace/range_list', 'ace/lib/oop'], function(require, exports, module) {
 
9501
 
 
9502
 
 
9503
var Range = require("../range").Range;
 
9504
var RangeList = require("../range_list").RangeList;
 
9505
var oop = require("../lib/oop")
 
9506
var Fold = exports.Fold = function(range, placeholder) {
 
9507
    this.foldLine = null;
 
9508
    this.placeholder = placeholder;
 
9509
    this.range = range;
 
9510
    this.start = range.start;
 
9511
    this.end = range.end;
 
9512
 
 
9513
    this.sameRow = range.start.row == range.end.row;
 
9514
    this.subFolds = this.ranges = [];
 
9515
};
 
9516
 
 
9517
oop.inherits(Fold, RangeList);
 
9518
 
 
9519
(function() {
 
9520
 
 
9521
    this.toString = function() {
 
9522
        return '"' + this.placeholder + '" ' + this.range.toString();
 
9523
    };
 
9524
 
 
9525
    this.setFoldLine = function(foldLine) {
 
9526
        this.foldLine = foldLine;
 
9527
        this.subFolds.forEach(function(fold) {
 
9528
            fold.setFoldLine(foldLine);
 
9529
        });
 
9530
    };
 
9531
 
 
9532
    this.clone = function() {
 
9533
        var range = this.range.clone();
 
9534
        var fold = new Fold(range, this.placeholder);
 
9535
        this.subFolds.forEach(function(subFold) {
 
9536
            fold.subFolds.push(subFold.clone());
 
9537
        });
 
9538
        fold.collapseChildren = this.collapseChildren;
 
9539
        return fold;
 
9540
    };
 
9541
 
 
9542
    this.addSubFold = function(fold) {
 
9543
        if (this.range.isEqual(fold))
 
9544
            return;
 
9545
 
 
9546
        if (!this.range.containsRange(fold))
 
9547
            throw "A fold can't intersect already existing fold" + fold.range + this.range;
 
9548
        consumeRange(fold, this.start);
 
9549
 
 
9550
        var row = fold.start.row, column = fold.start.column;
 
9551
        for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
 
9552
            cmp = this.subFolds[i].range.compare(row, column);
 
9553
            if (cmp != 1)
 
9554
                break;
 
9555
        }
 
9556
        var afterStart = this.subFolds[i];
 
9557
 
 
9558
        if (cmp == 0)
 
9559
            return afterStart.addSubFold(fold);
 
9560
        var row = fold.range.end.row, column = fold.range.end.column;
 
9561
        for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
 
9562
            cmp = this.subFolds[j].range.compare(row, column);
 
9563
            if (cmp != 1)
 
9564
                break;
 
9565
        }
 
9566
        var afterEnd = this.subFolds[j];
 
9567
 
 
9568
        if (cmp == 0)
 
9569
            throw "A fold can't intersect already existing fold" + fold.range + this.range;
 
9570
 
 
9571
        var consumedFolds = this.subFolds.splice(i, j - i, fold);
 
9572
        fold.setFoldLine(this.foldLine);
 
9573
 
 
9574
        return fold;
 
9575
    };
 
9576
    
 
9577
    this.restoreRange = function(range) {
 
9578
        return restoreRange(range, this.start);
 
9579
    };
 
9580
 
 
9581
}).call(Fold.prototype);
 
9582
 
 
9583
function consumePoint(point, anchor) {
 
9584
    point.row -= anchor.row;
 
9585
    if (point.row == 0)
 
9586
        point.column -= anchor.column;
 
9587
}
 
9588
function consumeRange(range, anchor) {
 
9589
    consumePoint(range.start, anchor);
 
9590
    consumePoint(range.end, anchor);
 
9591
}
 
9592
function restorePoint(point, anchor) {
 
9593
    if (point.row == 0)
 
9594
        point.column += anchor.column;
 
9595
    point.row += anchor.row;
 
9596
}
 
9597
function restoreRange(range, anchor) {
 
9598
    restorePoint(range.start, anchor);
 
9599
    restorePoint(range.end, anchor);
 
9600
}
 
9601
 
 
9602
});
 
9603
 
 
9604
define('ace/range_list', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
 
9605
 
 
9606
var Range = require("./range").Range;
 
9607
var comparePoints = Range.comparePoints;
 
9608
 
 
9609
var RangeList = function() {
 
9610
    this.ranges = [];
 
9611
};
 
9612
 
 
9613
(function() {
 
9614
    this.comparePoints = comparePoints;
 
9615
 
 
9616
    this.pointIndex = function(pos, excludeEdges, startIndex) {
 
9617
        var list = this.ranges;
 
9618
 
 
9619
        for (var i = startIndex || 0; i < list.length; i++) {
 
9620
            var range = list[i];
 
9621
            var cmpEnd = comparePoints(pos, range.end);
 
9622
            if (cmpEnd > 0)
 
9623
                continue;
 
9624
            var cmpStart = comparePoints(pos, range.start);
 
9625
            if (cmpEnd === 0)
 
9626
                return excludeEdges && cmpStart !== 0 ? -i-2 : i;
 
9627
            if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
 
9628
                return i;
 
9629
 
 
9630
            return -i-1;
 
9631
        }
 
9632
        return -i - 1;
 
9633
    };
 
9634
 
 
9635
    this.add = function(range) {
 
9636
        var excludeEdges = !range.isEmpty();
 
9637
        var startIndex = this.pointIndex(range.start, excludeEdges);
 
9638
        if (startIndex < 0)
 
9639
            startIndex = -startIndex - 1;
 
9640
 
 
9641
        var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
 
9642
 
 
9643
        if (endIndex < 0)
 
9644
            endIndex = -endIndex - 1;
 
9645
        else
 
9646
            endIndex++;
 
9647
        return this.ranges.splice(startIndex, endIndex - startIndex, range);
 
9648
    };
 
9649
 
 
9650
    this.addList = function(list) {
 
9651
        var removed = [];
 
9652
        for (var i = list.length; i--; ) {
 
9653
            removed.push.call(removed, this.add(list[i]));
 
9654
        }
 
9655
        return removed;
 
9656
    };
 
9657
 
 
9658
    this.substractPoint = function(pos) {
 
9659
        var i = this.pointIndex(pos);
 
9660
 
 
9661
        if (i >= 0)
 
9662
            return this.ranges.splice(i, 1);
 
9663
    };
 
9664
    this.merge = function() {
 
9665
        var removed = [];
 
9666
        var list = this.ranges;
 
9667
        
 
9668
        list = list.sort(function(a, b) {
 
9669
            return comparePoints(a.start, b.start);
 
9670
        });
 
9671
        
 
9672
        var next = list[0], range;
 
9673
        for (var i = 1; i < list.length; i++) {
 
9674
            range = next;
 
9675
            next = list[i];
 
9676
            var cmp = comparePoints(range.end, next.start);
 
9677
            if (cmp < 0)
 
9678
                continue;
 
9679
 
 
9680
            if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
 
9681
                continue;
 
9682
 
 
9683
            if (comparePoints(range.end, next.end) < 0) {
 
9684
                range.end.row = next.end.row;
 
9685
                range.end.column = next.end.column;
 
9686
            }
 
9687
 
 
9688
            list.splice(i, 1);
 
9689
            removed.push(next);
 
9690
            next = range;
 
9691
            i--;
 
9692
        }
 
9693
        
 
9694
        this.ranges = list;
 
9695
 
 
9696
        return removed;
 
9697
    };
 
9698
 
 
9699
    this.contains = function(row, column) {
 
9700
        return this.pointIndex({row: row, column: column}) >= 0;
 
9701
    };
 
9702
 
 
9703
    this.containsPoint = function(pos) {
 
9704
        return this.pointIndex(pos) >= 0;
 
9705
    };
 
9706
 
 
9707
    this.rangeAtPoint = function(pos) {
 
9708
        var i = this.pointIndex(pos);
 
9709
        if (i >= 0)
 
9710
            return this.ranges[i];
 
9711
    };
 
9712
 
 
9713
 
 
9714
    this.clipRows = function(startRow, endRow) {
 
9715
        var list = this.ranges;
 
9716
        if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)
 
9717
            return [];
 
9718
 
 
9719
        var startIndex = this.pointIndex({row: startRow, column: 0});
 
9720
        if (startIndex < 0)
 
9721
            startIndex = -startIndex - 1;
 
9722
        var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);
 
9723
        if (endIndex < 0)
 
9724
            endIndex = -endIndex - 1;
 
9725
 
 
9726
        var clipped = [];
 
9727
        for (var i = startIndex; i < endIndex; i++) {
 
9728
            clipped.push(list[i]);
 
9729
        }
 
9730
        return clipped;
 
9731
    };
 
9732
 
 
9733
    this.removeAll = function() {
 
9734
        return this.ranges.splice(0, this.ranges.length);
 
9735
    };
 
9736
 
 
9737
    this.attach = function(session) {
 
9738
        if (this.session)
 
9739
            this.detach();
 
9740
 
 
9741
        this.session = session;
 
9742
        this.onChange = this.$onChange.bind(this);
 
9743
 
 
9744
        this.session.on('change', this.onChange);
 
9745
    };
 
9746
 
 
9747
    this.detach = function() {
 
9748
        if (!this.session)
 
9749
            return;
 
9750
        this.session.removeListener('change', this.onChange);
 
9751
        this.session = null;
 
9752
    };
 
9753
 
 
9754
    this.$onChange = function(e) {
 
9755
        var changeRange = e.data.range;
 
9756
        if (e.data.action[0] == "i"){
 
9757
            var start = changeRange.start;
 
9758
            var end = changeRange.end;
 
9759
        } else {
 
9760
            var end = changeRange.start;
 
9761
            var start = changeRange.end;
 
9762
        }
 
9763
        var startRow = start.row;
 
9764
        var endRow = end.row;
 
9765
        var lineDif = endRow - startRow;
 
9766
 
 
9767
        var colDiff = -start.column + end.column;
 
9768
        var ranges = this.ranges;
 
9769
 
 
9770
        for (var i = 0, n = ranges.length; i < n; i++) {
 
9771
            var r = ranges[i];
 
9772
            if (r.end.row < startRow)
 
9773
                continue;
 
9774
            if (r.start.row > startRow)
 
9775
                break;
 
9776
 
 
9777
            if (r.start.row == startRow && r.start.column >= start.column ) {
 
9778
                
 
9779
                r.start.column += colDiff;
 
9780
                r.start.row += lineDif;
 
9781
            }
 
9782
            if (r.end.row == startRow && r.end.column >= start.column) {
 
9783
                if (r.end.column == start.column && colDiff > 0 && i < n - 1) {                
 
9784
                    if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
 
9785
                        r.end.column -= colDiff;
 
9786
                }
 
9787
                r.end.column += colDiff;
 
9788
                r.end.row += lineDif;
 
9789
            }
 
9790
        }
 
9791
 
 
9792
        if (lineDif != 0 && i < n) {
 
9793
            for (; i < n; i++) {
 
9794
                var r = ranges[i];
 
9795
                r.start.row += lineDif;
 
9796
                r.end.row += lineDif;
 
9797
            }
 
9798
        }
 
9799
    };
 
9800
 
 
9801
}).call(RangeList.prototype);
 
9802
 
 
9803
exports.RangeList = RangeList;
 
9804
});
 
9805
 
 
9806
define('ace/token_iterator', ['require', 'exports', 'module' ], function(require, exports, module) {
 
9807
var TokenIterator = function(session, initialRow, initialColumn) {
 
9808
    this.$session = session;
 
9809
    this.$row = initialRow;
 
9810
    this.$rowTokens = session.getTokens(initialRow);
 
9811
 
 
9812
    var token = session.getTokenAt(initialRow, initialColumn);
 
9813
    this.$tokenIndex = token ? token.index : -1;
 
9814
};
 
9815
 
 
9816
(function() { 
 
9817
    this.stepBackward = function() {
 
9818
        this.$tokenIndex -= 1;
 
9819
        
 
9820
        while (this.$tokenIndex < 0) {
 
9821
            this.$row -= 1;
 
9822
            if (this.$row < 0) {
 
9823
                this.$row = 0;
 
9824
                return null;
 
9825
            }
 
9826
                
 
9827
            this.$rowTokens = this.$session.getTokens(this.$row);
 
9828
            this.$tokenIndex = this.$rowTokens.length - 1;
 
9829
        }
 
9830
            
 
9831
        return this.$rowTokens[this.$tokenIndex];
 
9832
    };   
 
9833
    this.stepForward = function() {
 
9834
        this.$tokenIndex += 1;
 
9835
        var rowCount;
 
9836
        while (this.$tokenIndex >= this.$rowTokens.length) {
 
9837
            this.$row += 1;
 
9838
            if (!rowCount)
 
9839
                rowCount = this.$session.getLength();
 
9840
            if (this.$row >= rowCount) {
 
9841
                this.$row = rowCount - 1;
 
9842
                return null;
 
9843
            }
 
9844
 
 
9845
            this.$rowTokens = this.$session.getTokens(this.$row);
 
9846
            this.$tokenIndex = 0;
 
9847
        }
 
9848
            
 
9849
        return this.$rowTokens[this.$tokenIndex];
 
9850
    };      
 
9851
    this.getCurrentToken = function () {
 
9852
        return this.$rowTokens[this.$tokenIndex];
 
9853
    };      
 
9854
    this.getCurrentTokenRow = function () {
 
9855
        return this.$row;
 
9856
    };     
 
9857
    this.getCurrentTokenColumn = function() {
 
9858
        var rowTokens = this.$rowTokens;
 
9859
        var tokenIndex = this.$tokenIndex;
 
9860
        var column = rowTokens[tokenIndex].start;
 
9861
        if (column !== undefined)
 
9862
            return column;
 
9863
            
 
9864
        column = 0;
 
9865
        while (tokenIndex > 0) {
 
9866
            tokenIndex -= 1;
 
9867
            column += rowTokens[tokenIndex].value.length;
 
9868
        }
 
9869
        
 
9870
        return column;  
 
9871
    };
 
9872
            
 
9873
}).call(TokenIterator.prototype);
 
9874
 
 
9875
exports.TokenIterator = TokenIterator;
 
9876
});
 
9877
 
 
9878
define('ace/edit_session/bracket_match', ['require', 'exports', 'module' , 'ace/token_iterator', 'ace/range'], function(require, exports, module) {
 
9879
 
 
9880
 
 
9881
var TokenIterator = require("../token_iterator").TokenIterator;
 
9882
var Range = require("../range").Range;
 
9883
 
 
9884
 
 
9885
function BracketMatch() {
 
9886
 
 
9887
    this.findMatchingBracket = function(position, chr) {
 
9888
        if (position.column == 0) return null;
 
9889
 
 
9890
        var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);
 
9891
        if (charBeforeCursor == "") return null;
 
9892
 
 
9893
        var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
 
9894
        if (!match)
 
9895
            return null;
 
9896
 
 
9897
        if (match[1])
 
9898
            return this.$findClosingBracket(match[1], position);
 
9899
        else
 
9900
            return this.$findOpeningBracket(match[2], position);
 
9901
    };
 
9902
    
 
9903
    this.getBracketRange = function(pos) {
 
9904
        var line = this.getLine(pos.row);
 
9905
        var before = true, range;
 
9906
 
 
9907
        var chr = line.charAt(pos.column-1);
 
9908
        var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
 
9909
        if (!match) {
 
9910
            chr = line.charAt(pos.column);
 
9911
            pos = {row: pos.row, column: pos.column + 1};
 
9912
            match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
 
9913
            before = false;
 
9914
        }
 
9915
        if (!match)
 
9916
            return null;
 
9917
 
 
9918
        if (match[1]) {
 
9919
            var bracketPos = this.$findClosingBracket(match[1], pos);
 
9920
            if (!bracketPos)
 
9921
                return null;
 
9922
            range = Range.fromPoints(pos, bracketPos);
 
9923
            if (!before) {
 
9924
                range.end.column++;
 
9925
                range.start.column--;
 
9926
            }
 
9927
            range.cursor = range.end;
 
9928
        } else {
 
9929
            var bracketPos = this.$findOpeningBracket(match[2], pos);
 
9930
            if (!bracketPos)
 
9931
                return null;
 
9932
            range = Range.fromPoints(bracketPos, pos);
 
9933
            if (!before) {
 
9934
                range.start.column++;
 
9935
                range.end.column--;
 
9936
            }
 
9937
            range.cursor = range.start;
 
9938
        }
 
9939
        
 
9940
        return range;
 
9941
    };
 
9942
 
 
9943
    this.$brackets = {
 
9944
        ")": "(",
 
9945
        "(": ")",
 
9946
        "]": "[",
 
9947
        "[": "]",
 
9948
        "{": "}",
 
9949
        "}": "{"
 
9950
    };
 
9951
 
 
9952
    this.$findOpeningBracket = function(bracket, position, typeRe) {
 
9953
        var openBracket = this.$brackets[bracket];
 
9954
        var depth = 1;
 
9955
 
 
9956
        var iterator = new TokenIterator(this, position.row, position.column);
 
9957
        var token = iterator.getCurrentToken();
 
9958
        if (!token)
 
9959
            token = iterator.stepForward();
 
9960
        if (!token)
 
9961
            return;
 
9962
        
 
9963
         if (!typeRe){
 
9964
            typeRe = new RegExp(
 
9965
                "(\\.?" +
 
9966
                token.type.replace(".", "\\.").replace("rparen", ".paren")
 
9967
                + ")+"
 
9968
            );
 
9969
        }
 
9970
        var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
 
9971
        var value = token.value;
 
9972
        
 
9973
        while (true) {
 
9974
        
 
9975
            while (valueIndex >= 0) {
 
9976
                var chr = value.charAt(valueIndex);
 
9977
                if (chr == openBracket) {
 
9978
                    depth -= 1;
 
9979
                    if (depth == 0) {
 
9980
                        return {row: iterator.getCurrentTokenRow(),
 
9981
                            column: valueIndex + iterator.getCurrentTokenColumn()};
 
9982
                    }
 
9983
                }
 
9984
                else if (chr == bracket) {
 
9985
                    depth += 1;
 
9986
                }
 
9987
                valueIndex -= 1;
 
9988
            }
 
9989
            do {
 
9990
                token = iterator.stepBackward();
 
9991
            } while (token && !typeRe.test(token.type));
 
9992
 
 
9993
            if (token == null)
 
9994
                break;
 
9995
                
 
9996
            value = token.value;
 
9997
            valueIndex = value.length - 1;
 
9998
        }
 
9999
        
 
10000
        return null;
 
10001
    };
 
10002
 
 
10003
    this.$findClosingBracket = function(bracket, position, typeRe) {
 
10004
        var closingBracket = this.$brackets[bracket];
 
10005
        var depth = 1;
 
10006
 
 
10007
        var iterator = new TokenIterator(this, position.row, position.column);
 
10008
        var token = iterator.getCurrentToken();
 
10009
        if (!token)
 
10010
            token = iterator.stepForward();
 
10011
        if (!token)
 
10012
            return;
 
10013
 
 
10014
        if (!typeRe){
 
10015
            typeRe = new RegExp(
 
10016
                "(\\.?" +
 
10017
                token.type.replace(".", "\\.").replace("lparen", ".paren")
 
10018
                + ")+"
 
10019
            );
 
10020
        }
 
10021
        var valueIndex = position.column - iterator.getCurrentTokenColumn();
 
10022
 
 
10023
        while (true) {
 
10024
 
 
10025
            var value = token.value;
 
10026
            var valueLength = value.length;
 
10027
            while (valueIndex < valueLength) {
 
10028
                var chr = value.charAt(valueIndex);
 
10029
                if (chr == closingBracket) {
 
10030
                    depth -= 1;
 
10031
                    if (depth == 0) {
 
10032
                        return {row: iterator.getCurrentTokenRow(),
 
10033
                            column: valueIndex + iterator.getCurrentTokenColumn()};
 
10034
                    }
 
10035
                }
 
10036
                else if (chr == bracket) {
 
10037
                    depth += 1;
 
10038
                }
 
10039
                valueIndex += 1;
 
10040
            }
 
10041
            do {
 
10042
                token = iterator.stepForward();
 
10043
            } while (token && !typeRe.test(token.type));
 
10044
 
 
10045
            if (token == null)
 
10046
                break;
 
10047
 
 
10048
            valueIndex = 0;
 
10049
        }
 
10050
        
 
10051
        return null;
 
10052
    };
 
10053
}
 
10054
exports.BracketMatch = BracketMatch;
 
10055
 
 
10056
});
 
10057
 
 
10058
define('ace/search', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
 
10059
 
 
10060
 
 
10061
var lang = require("./lib/lang");
 
10062
var oop = require("./lib/oop");
 
10063
var Range = require("./range").Range;
 
10064
 
 
10065
var Search = function() {
 
10066
    this.$options = {};
 
10067
};
 
10068
 
 
10069
(function() {
 
10070
    this.set = function(options) {
 
10071
        oop.mixin(this.$options, options);
 
10072
        return this;
 
10073
    };
 
10074
    this.getOptions = function() {
 
10075
        return lang.copyObject(this.$options);
 
10076
    };
 
10077
    this.setOptions = function(options) {
 
10078
        this.$options = options;
 
10079
    };
 
10080
    this.find = function(session) {
 
10081
        var iterator = this.$matchIterator(session, this.$options);
 
10082
 
 
10083
        if (!iterator)
 
10084
            return false;
 
10085
 
 
10086
        var firstRange = null;
 
10087
        iterator.forEach(function(range, row, offset) {
 
10088
            if (!range.start) {
 
10089
                var column = range.offset + (offset || 0);
 
10090
                firstRange = new Range(row, column, row, column+range.length);
 
10091
            } else
 
10092
                firstRange = range;
 
10093
            return true;
 
10094
        });
 
10095
 
 
10096
        return firstRange;
 
10097
    };
 
10098
    this.findAll = function(session) {
 
10099
        var options = this.$options;
 
10100
        if (!options.needle)
 
10101
            return [];
 
10102
        this.$assembleRegExp(options);
 
10103
 
 
10104
        var range = options.range;
 
10105
        var lines = range
 
10106
            ? session.getLines(range.start.row, range.end.row)
 
10107
            : session.doc.getAllLines();
 
10108
 
 
10109
        var ranges = [];
 
10110
        var re = options.re;
 
10111
        if (options.$isMultiLine) {
 
10112
            var len = re.length;
 
10113
            var maxRow = lines.length - len;
 
10114
            for (var row = re.offset || 0; row <= maxRow; row++) {
 
10115
                for (var j = 0; j < len; j++)
 
10116
                    if (lines[row + j].search(re[j]) == -1)
 
10117
                        break;
 
10118
                
 
10119
                var startLine = lines[row];
 
10120
                var line = lines[row + len - 1];
 
10121
                var startIndex = startLine.match(re[0])[0].length;
 
10122
                var endIndex = line.match(re[len - 1])[0].length;
 
10123
 
 
10124
                ranges.push(new Range(
 
10125
                    row, startLine.length - startIndex,
 
10126
                    row + len - 1, endIndex
 
10127
                ));
 
10128
            }
 
10129
        } else {
 
10130
            for (var i = 0; i < lines.length; i++) {
 
10131
                var matches = lang.getMatchOffsets(lines[i], re);
 
10132
                for (var j = 0; j < matches.length; j++) {
 
10133
                    var match = matches[j];
 
10134
                    ranges.push(new Range(i, match.offset, i, match.offset + match.length));
 
10135
                }
 
10136
            }
 
10137
        }
 
10138
 
 
10139
        if (range) {
 
10140
            var startColumn = range.start.column;
 
10141
            var endColumn = range.start.column;
 
10142
            var i = 0, j = ranges.length - 1;
 
10143
            while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row)
 
10144
                i++;
 
10145
 
 
10146
            while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row)
 
10147
                j--;
 
10148
            return ranges.slice(i, j + 1);
 
10149
        }
 
10150
 
 
10151
        return ranges;
 
10152
    };
 
10153
    this.replace = function(input, replacement) {
 
10154
        var options = this.$options;
 
10155
 
 
10156
        var re = this.$assembleRegExp(options);
 
10157
        if (options.$isMultiLine)
 
10158
            return replacement;
 
10159
 
 
10160
        if (!re)
 
10161
            return;
 
10162
 
 
10163
        var match = re.exec(input);
 
10164
        if (!match || match[0].length != input.length)
 
10165
            return null;
 
10166
        
 
10167
        replacement = input.replace(re, replacement);
 
10168
        if (options.preserveCase) {
 
10169
            replacement = replacement.split("");
 
10170
            for (var i = Math.min(input.length, input.length); i--; ) {
 
10171
                var ch = input[i];
 
10172
                if (ch && ch.toLowerCase() != ch)
 
10173
                    replacement[i] = replacement[i].toUpperCase();
 
10174
                else
 
10175
                    replacement[i] = replacement[i].toLowerCase();
 
10176
            }
 
10177
            replacement = replacement.join("");
 
10178
        }
 
10179
        
 
10180
        return replacement;
 
10181
    };
 
10182
 
 
10183
    this.$matchIterator = function(session, options) {
 
10184
        var re = this.$assembleRegExp(options);
 
10185
        if (!re)
 
10186
            return false;
 
10187
 
 
10188
        var self = this, callback, backwards = options.backwards;
 
10189
 
 
10190
        if (options.$isMultiLine) {
 
10191
            var len = re.length;
 
10192
            var matchIterator = function(line, row, offset) {
 
10193
                var startIndex = line.search(re[0]);
 
10194
                if (startIndex == -1)
 
10195
                    return;
 
10196
                for (var i = 1; i < len; i++) {
 
10197
                    line = session.getLine(row + i);
 
10198
                    if (line.search(re[i]) == -1)
 
10199
                        return;
 
10200
                }
 
10201
 
 
10202
                var endIndex = line.match(re[len - 1])[0].length;
 
10203
 
 
10204
                var range = new Range(row, startIndex, row + len - 1, endIndex);
 
10205
                if (re.offset == 1) {
 
10206
                    range.start.row--;
 
10207
                    range.start.column = Number.MAX_VALUE;
 
10208
                } else if (offset)
 
10209
                    range.start.column += offset;
 
10210
 
 
10211
                if (callback(range))
 
10212
                    return true;
 
10213
            };
 
10214
        } else if (backwards) {
 
10215
            var matchIterator = function(line, row, startIndex) {
 
10216
                var matches = lang.getMatchOffsets(line, re);
 
10217
                for (var i = matches.length-1; i >= 0; i--)
 
10218
                    if (callback(matches[i], row, startIndex))
 
10219
                        return true;
 
10220
            };
 
10221
        } else {
 
10222
            var matchIterator = function(line, row, startIndex) {
 
10223
                var matches = lang.getMatchOffsets(line, re);
 
10224
                for (var i = 0; i < matches.length; i++)
 
10225
                    if (callback(matches[i], row, startIndex))
 
10226
                        return true;
 
10227
            };
 
10228
        }
 
10229
 
 
10230
        return {
 
10231
            forEach: function(_callback) {
 
10232
                callback = _callback;
 
10233
                self.$lineIterator(session, options).forEach(matchIterator);
 
10234
            }
 
10235
        };
 
10236
    };
 
10237
 
 
10238
    this.$assembleRegExp = function(options) {
 
10239
        if (options.needle instanceof RegExp)
 
10240
            return options.re = options.needle;
 
10241
 
 
10242
        var needle = options.needle;
 
10243
 
 
10244
        if (!options.needle)
 
10245
            return options.re = false;
 
10246
 
 
10247
        if (!options.regExp)
 
10248
            needle = lang.escapeRegExp(needle);
 
10249
 
 
10250
        if (options.wholeWord)
 
10251
            needle = "\\b" + needle + "\\b";
 
10252
 
 
10253
        var modifier = options.caseSensitive ? "g" : "gi";
 
10254
 
 
10255
        options.$isMultiLine = /[\n\r]/.test(needle);
 
10256
        if (options.$isMultiLine)
 
10257
            return options.re = this.$assembleMultilineRegExp(needle, modifier);
 
10258
 
 
10259
        try {
 
10260
            var re = new RegExp(needle, modifier);
 
10261
        } catch(e) {
 
10262
            re = false;
 
10263
        }
 
10264
        return options.re = re;
 
10265
    };
 
10266
 
 
10267
    this.$assembleMultilineRegExp = function(needle, modifier) {
 
10268
        var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n");
 
10269
        var re = [];
 
10270
        for (var i = 0; i < parts.length; i++) try {
 
10271
            re.push(new RegExp(parts[i], modifier));
 
10272
        } catch(e) {
 
10273
            return false;
 
10274
        }
 
10275
        if (parts[0] == "") {
 
10276
            re.shift();
 
10277
            re.offset = 1;
 
10278
        } else {
 
10279
            re.offset = 0;
 
10280
        }
 
10281
        return re;
 
10282
    };
 
10283
 
 
10284
    this.$lineIterator = function(session, options) {
 
10285
        var backwards = options.backwards == true;
 
10286
        var skipCurrent = options.skipCurrent != false;
 
10287
 
 
10288
        var range = options.range;
 
10289
        var start = options.start;
 
10290
        if (!start)
 
10291
            start = range ? range[backwards ? "end" : "start"] : session.selection.getRange();
 
10292
         
 
10293
        if (start.start)
 
10294
            start = start[skipCurrent != backwards ? "end" : "start"];
 
10295
 
 
10296
        var firstRow = range ? range.start.row : 0;
 
10297
        var lastRow = range ? range.end.row : session.getLength() - 1;
 
10298
 
 
10299
        var forEach = backwards ? function(callback) {
 
10300
                var row = start.row;
 
10301
 
 
10302
                var line = session.getLine(row).substring(0, start.column);
 
10303
                if (callback(line, row))
 
10304
                    return;
 
10305
 
 
10306
                for (row--; row >= firstRow; row--)
 
10307
                    if (callback(session.getLine(row), row))
 
10308
                        return;
 
10309
 
 
10310
                if (options.wrap == false)
 
10311
                    return;
 
10312
 
 
10313
                for (row = lastRow, firstRow = start.row; row >= firstRow; row--)
 
10314
                    if (callback(session.getLine(row), row))
 
10315
                        return;
 
10316
            } : function(callback) {
 
10317
                var row = start.row;
 
10318
 
 
10319
                var line = session.getLine(row).substr(start.column);
 
10320
                if (callback(line, row, start.column))
 
10321
                    return;
 
10322
 
 
10323
                for (row = row+1; row <= lastRow; row++)
 
10324
                    if (callback(session.getLine(row), row))
 
10325
                        return;
 
10326
 
 
10327
                if (options.wrap == false)
 
10328
                    return;
 
10329
 
 
10330
                for (row = firstRow, lastRow = start.row; row <= lastRow; row++)
 
10331
                    if (callback(session.getLine(row), row))
 
10332
                        return;
 
10333
            };
 
10334
        
 
10335
        return {forEach: forEach};
 
10336
    };
 
10337
 
 
10338
}).call(Search.prototype);
 
10339
 
 
10340
exports.Search = Search;
 
10341
});
 
10342
define('ace/commands/command_manager', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/keyboard/hash_handler', 'ace/lib/event_emitter'], function(require, exports, module) {
 
10343
 
 
10344
 
 
10345
var oop = require("../lib/oop");
 
10346
var HashHandler = require("../keyboard/hash_handler").HashHandler;
 
10347
var EventEmitter = require("../lib/event_emitter").EventEmitter;
 
10348
 
 
10349
var CommandManager = function(platform, commands) {
 
10350
    this.platform = platform;
 
10351
    this.commands = this.byName = {};
 
10352
    this.commmandKeyBinding = {};
 
10353
 
 
10354
    this.addCommands(commands);
 
10355
 
 
10356
    this.setDefaultHandler("exec", function(e) {
 
10357
        return e.command.exec(e.editor, e.args || {});
 
10358
    });
 
10359
};
 
10360
 
 
10361
oop.inherits(CommandManager, HashHandler);
 
10362
 
 
10363
(function() {
 
10364
 
 
10365
    oop.implement(this, EventEmitter);
 
10366
 
 
10367
    this.exec = function(command, editor, args) {
 
10368
        if (typeof command === 'string')
 
10369
            command = this.commands[command];
 
10370
 
 
10371
        if (!command)
 
10372
            return false;
 
10373
 
 
10374
        if (editor && editor.$readOnly && !command.readOnly)
 
10375
            return false;
 
10376
 
 
10377
        var e = {editor: editor, command: command, args: args};
 
10378
        var retvalue = this._emit("exec", e);
 
10379
        this._signal("afterExec", e);
 
10380
 
 
10381
        return retvalue === false ? false : true;
 
10382
    };
 
10383
 
 
10384
    this.toggleRecording = function(editor) {
 
10385
        if (this.$inReplay)
 
10386
            return;
 
10387
 
 
10388
        editor && editor._emit("changeStatus");
 
10389
        if (this.recording) {
 
10390
            this.macro.pop();
 
10391
            this.removeEventListener("exec", this.$addCommandToMacro);
 
10392
 
 
10393
            if (!this.macro.length)
 
10394
                this.macro = this.oldMacro;
 
10395
 
 
10396
            return this.recording = false;
 
10397
        }
 
10398
        if (!this.$addCommandToMacro) {
 
10399
            this.$addCommandToMacro = function(e) {
 
10400
                this.macro.push([e.command, e.args]);
 
10401
            }.bind(this);
 
10402
        }
 
10403
 
 
10404
        this.oldMacro = this.macro;
 
10405
        this.macro = [];
 
10406
        this.on("exec", this.$addCommandToMacro);
 
10407
        return this.recording = true;
 
10408
    };
 
10409
 
 
10410
    this.replay = function(editor) {
 
10411
        if (this.$inReplay || !this.macro)
 
10412
            return;
 
10413
 
 
10414
        if (this.recording)
 
10415
            return this.toggleRecording(editor);
 
10416
 
 
10417
        try {
 
10418
            this.$inReplay = true;
 
10419
            this.macro.forEach(function(x) {
 
10420
                if (typeof x == "string")
 
10421
                    this.exec(x, editor);
 
10422
                else
 
10423
                    this.exec(x[0], editor, x[1]);
 
10424
            }, this);
 
10425
        } finally {
 
10426
            this.$inReplay = false;
 
10427
        }
 
10428
    };
 
10429
 
 
10430
    this.trimMacro = function(m) {
 
10431
        return m.map(function(x){
 
10432
            if (typeof x[0] != "string")
 
10433
                x[0] = x[0].name;
 
10434
            if (!x[1])
 
10435
                x = x[0];
 
10436
            return x;
 
10437
        });
 
10438
    };
 
10439
 
 
10440
}).call(CommandManager.prototype);
 
10441
 
 
10442
exports.CommandManager = CommandManager;
 
10443
 
 
10444
});
 
10445
 
 
10446
define('ace/keyboard/hash_handler', ['require', 'exports', 'module' , 'ace/lib/keys'], function(require, exports, module) {
 
10447
 
 
10448
 
 
10449
var keyUtil = require("../lib/keys");
 
10450
 
 
10451
function HashHandler(config, platform) {
 
10452
    this.platform = platform;
 
10453
    this.commands = {};
 
10454
    this.commmandKeyBinding = {};
 
10455
 
 
10456
    this.addCommands(config);
 
10457
};
 
10458
 
 
10459
(function() {
 
10460
 
 
10461
    this.addCommand = function(command) {
 
10462
        if (this.commands[command.name])
 
10463
            this.removeCommand(command);
 
10464
 
 
10465
        this.commands[command.name] = command;
 
10466
 
 
10467
        if (command.bindKey)
 
10468
            this._buildKeyHash(command);
 
10469
    };
 
10470
 
 
10471
    this.removeCommand = function(command) {
 
10472
        var name = (typeof command === 'string' ? command : command.name);
 
10473
        command = this.commands[name];
 
10474
        delete this.commands[name];
 
10475
        var ckb = this.commmandKeyBinding;
 
10476
        for (var hashId in ckb) {
 
10477
            for (var key in ckb[hashId]) {
 
10478
                if (ckb[hashId][key] == command)
 
10479
                    delete ckb[hashId][key];
 
10480
            }
 
10481
        }
 
10482
    };
 
10483
 
 
10484
    this.bindKey = function(key, command) {
 
10485
        if(!key)
 
10486
            return;
 
10487
        if (typeof command == "function") {
 
10488
            this.addCommand({exec: command, bindKey: key, name: command.name || key});
 
10489
            return;
 
10490
        }
 
10491
 
 
10492
        var ckb = this.commmandKeyBinding;
 
10493
        key.split("|").forEach(function(keyPart) {
 
10494
            var binding = this.parseKeys(keyPart, command);
 
10495
            var hashId = binding.hashId;
 
10496
            (ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
 
10497
        }, this);
 
10498
    };
 
10499
 
 
10500
    this.addCommands = function(commands) {
 
10501
        commands && Object.keys(commands).forEach(function(name) {
 
10502
            var command = commands[name];
 
10503
            if (typeof command === "string")
 
10504
                return this.bindKey(command, name);
 
10505
 
 
10506
            if (typeof command === "function")
 
10507
                command = { exec: command };
 
10508
 
 
10509
            if (!command.name)
 
10510
                command.name = name;
 
10511
 
 
10512
            this.addCommand(command);
 
10513
        }, this);
 
10514
    };
 
10515
 
 
10516
    this.removeCommands = function(commands) {
 
10517
        Object.keys(commands).forEach(function(name) {
 
10518
            this.removeCommand(commands[name]);
 
10519
        }, this);
 
10520
    };
 
10521
 
 
10522
    this.bindKeys = function(keyList) {
 
10523
        Object.keys(keyList).forEach(function(key) {
 
10524
            this.bindKey(key, keyList[key]);
 
10525
        }, this);
 
10526
    };
 
10527
 
 
10528
    this._buildKeyHash = function(command) {
 
10529
        var binding = command.bindKey;
 
10530
        if (!binding)
 
10531
            return;
 
10532
 
 
10533
        var key = typeof binding == "string" ? binding: binding[this.platform];
 
10534
        this.bindKey(key, command);
 
10535
    };
 
10536
    this.parseKeys = function(keys) {
 
10537
        if (keys.indexOf(" ") != -1)
 
10538
            keys = keys.split(/\s+/).pop();
 
10539
 
 
10540
        var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x});
 
10541
        var key = parts.pop();
 
10542
 
 
10543
        var keyCode = keyUtil[key];
 
10544
        if (keyUtil.FUNCTION_KEYS[keyCode])
 
10545
            key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();
 
10546
        else if (!parts.length)
 
10547
            return {key: key, hashId: -1};
 
10548
        else if (parts.length == 1 && parts[0] == "shift")
 
10549
            return {key: key.toUpperCase(), hashId: -1};
 
10550
 
 
10551
        var hashId = 0;
 
10552
        for (var i = parts.length; i--;) {
 
10553
            var modifier = keyUtil.KEY_MODS[parts[i]];
 
10554
            if (modifier == null) {
 
10555
                if (typeof console != "undefined")
 
10556
                console.error("invalid modifier " + parts[i] + " in " + keys);
 
10557
                return false;
 
10558
            }
 
10559
            hashId |= modifier;
 
10560
        }
 
10561
        return {key: key, hashId: hashId};
 
10562
    };
 
10563
 
 
10564
    this.findKeyCommand = function findKeyCommand(hashId, keyString) {
 
10565
        var ckbr = this.commmandKeyBinding;
 
10566
        return ckbr[hashId] && ckbr[hashId][keyString];
 
10567
    };
 
10568
 
 
10569
    this.handleKeyboard = function(data, hashId, keyString, keyCode) {
 
10570
        return {
 
10571
            command: this.findKeyCommand(hashId, keyString)
 
10572
        };
 
10573
    };
 
10574
 
 
10575
}).call(HashHandler.prototype)
 
10576
 
 
10577
exports.HashHandler = HashHandler;
 
10578
});
 
10579
 
 
10580
define('ace/commands/default_commands', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/config'], function(require, exports, module) {
 
10581
 
 
10582
 
 
10583
var lang = require("../lib/lang");
 
10584
var config = require("../config");
 
10585
 
 
10586
function bindKey(win, mac) {
 
10587
    return {
 
10588
        win: win,
 
10589
        mac: mac
 
10590
    };
 
10591
}
 
10592
 
 
10593
exports.commands = [{
 
10594
    name: "selectall",
 
10595
    bindKey: bindKey("Ctrl-A", "Command-A"),
 
10596
    exec: function(editor) { editor.selectAll(); },
 
10597
    readOnly: true
 
10598
}, {
 
10599
    name: "centerselection",
 
10600
    bindKey: bindKey(null, "Ctrl-L"),
 
10601
    exec: function(editor) { editor.centerSelection(); },
 
10602
    readOnly: true
 
10603
}, {
 
10604
    name: "gotoline",
 
10605
    bindKey: bindKey("Ctrl-L", "Command-L"),
 
10606
    exec: function(editor) {
 
10607
        var line = parseInt(prompt("Enter line number:"), 10);
 
10608
        if (!isNaN(line)) {
 
10609
            editor.gotoLine(line);
 
10610
        }
 
10611
    },
 
10612
    readOnly: true
 
10613
}, {
 
10614
    name: "fold",
 
10615
    bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
 
10616
    exec: function(editor) { editor.session.toggleFold(false); },
 
10617
    readOnly: true
 
10618
}, {
 
10619
    name: "unfold",
 
10620
    bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
 
10621
    exec: function(editor) { editor.session.toggleFold(true); },
 
10622
    readOnly: true
 
10623
}, {
 
10624
    name: "foldall",
 
10625
    bindKey: bindKey("Alt-0", "Command-Option-0"),
 
10626
    exec: function(editor) { editor.session.foldAll(); },
 
10627
    readOnly: true
 
10628
}, {
 
10629
    name: "unfoldall",
 
10630
    bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
 
10631
    exec: function(editor) { editor.session.unfold(); },
 
10632
    readOnly: true
 
10633
}, {
 
10634
    name: "findnext",
 
10635
    bindKey: bindKey("Ctrl-K", "Command-G"),
 
10636
    exec: function(editor) { editor.findNext(); },
 
10637
    readOnly: true
 
10638
}, {
 
10639
    name: "findprevious",
 
10640
    bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
 
10641
    exec: function(editor) { editor.findPrevious(); },
 
10642
    readOnly: true
 
10643
}, {
 
10644
    name: "find",
 
10645
    bindKey: bindKey("Ctrl-F", "Command-F"),
 
10646
    exec: function(editor) {
 
10647
        config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)});
 
10648
    },
 
10649
    readOnly: true
 
10650
}, {
 
10651
    name: "overwrite",
 
10652
    bindKey: "Insert",
 
10653
    exec: function(editor) { editor.toggleOverwrite(); },
 
10654
    readOnly: true
 
10655
}, {
 
10656
    name: "selecttostart",
 
10657
    bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"),
 
10658
    exec: function(editor) { editor.getSelection().selectFileStart(); },
 
10659
    multiSelectAction: "forEach",
 
10660
    readOnly: true
 
10661
}, {
 
10662
    name: "gotostart",
 
10663
    bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
 
10664
    exec: function(editor) { editor.navigateFileStart(); },
 
10665
    multiSelectAction: "forEach",
 
10666
    readOnly: true
 
10667
}, {
 
10668
    name: "selectup",
 
10669
    bindKey: bindKey("Shift-Up", "Shift-Up"),
 
10670
    exec: function(editor) { editor.getSelection().selectUp(); },
 
10671
    multiSelectAction: "forEach",
 
10672
    readOnly: true
 
10673
}, {
 
10674
    name: "golineup",
 
10675
    bindKey: bindKey("Up", "Up|Ctrl-P"),
 
10676
    exec: function(editor, args) { editor.navigateUp(args.times); },
 
10677
    multiSelectAction: "forEach",
 
10678
    readOnly: true
 
10679
}, {
 
10680
    name: "selecttoend",
 
10681
    bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"),
 
10682
    exec: function(editor) { editor.getSelection().selectFileEnd(); },
 
10683
    multiSelectAction: "forEach",
 
10684
    readOnly: true
 
10685
}, {
 
10686
    name: "gotoend",
 
10687
    bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
 
10688
    exec: function(editor) { editor.navigateFileEnd(); },
 
10689
    multiSelectAction: "forEach",
 
10690
    readOnly: true
 
10691
}, {
 
10692
    name: "selectdown",
 
10693
    bindKey: bindKey("Shift-Down", "Shift-Down"),
 
10694
    exec: function(editor) { editor.getSelection().selectDown(); },
 
10695
    multiSelectAction: "forEach",
 
10696
    readOnly: true
 
10697
}, {
 
10698
    name: "golinedown",
 
10699
    bindKey: bindKey("Down", "Down|Ctrl-N"),
 
10700
    exec: function(editor, args) { editor.navigateDown(args.times); },
 
10701
    multiSelectAction: "forEach",
 
10702
    readOnly: true
 
10703
}, {
 
10704
    name: "selectwordleft",
 
10705
    bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
 
10706
    exec: function(editor) { editor.getSelection().selectWordLeft(); },
 
10707
    multiSelectAction: "forEach",
 
10708
    readOnly: true
 
10709
}, {
 
10710
    name: "gotowordleft",
 
10711
    bindKey: bindKey("Ctrl-Left", "Option-Left"),
 
10712
    exec: function(editor) { editor.navigateWordLeft(); },
 
10713
    multiSelectAction: "forEach",
 
10714
    readOnly: true
 
10715
}, {
 
10716
    name: "selecttolinestart",
 
10717
    bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"),
 
10718
    exec: function(editor) { editor.getSelection().selectLineStart(); },
 
10719
    multiSelectAction: "forEach",
 
10720
    readOnly: true
 
10721
}, {
 
10722
    name: "gotolinestart",
 
10723
    bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
 
10724
    exec: function(editor) { editor.navigateLineStart(); },
 
10725
    multiSelectAction: "forEach",
 
10726
    readOnly: true
 
10727
}, {
 
10728
    name: "selectleft",
 
10729
    bindKey: bindKey("Shift-Left", "Shift-Left"),
 
10730
    exec: function(editor) { editor.getSelection().selectLeft(); },
 
10731
    multiSelectAction: "forEach",
 
10732
    readOnly: true
 
10733
}, {
 
10734
    name: "gotoleft",
 
10735
    bindKey: bindKey("Left", "Left|Ctrl-B"),
 
10736
    exec: function(editor, args) { editor.navigateLeft(args.times); },
 
10737
    multiSelectAction: "forEach",
 
10738
    readOnly: true
 
10739
}, {
 
10740
    name: "selectwordright",
 
10741
    bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
 
10742
    exec: function(editor) { editor.getSelection().selectWordRight(); },
 
10743
    multiSelectAction: "forEach",
 
10744
    readOnly: true
 
10745
}, {
 
10746
    name: "gotowordright",
 
10747
    bindKey: bindKey("Ctrl-Right", "Option-Right"),
 
10748
    exec: function(editor) { editor.navigateWordRight(); },
 
10749
    multiSelectAction: "forEach",
 
10750
    readOnly: true
 
10751
}, {
 
10752
    name: "selecttolineend",
 
10753
    bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"),
 
10754
    exec: function(editor) { editor.getSelection().selectLineEnd(); },
 
10755
    multiSelectAction: "forEach",
 
10756
    readOnly: true
 
10757
}, {
 
10758
    name: "gotolineend",
 
10759
    bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
 
10760
    exec: function(editor) { editor.navigateLineEnd(); },
 
10761
    multiSelectAction: "forEach",
 
10762
    readOnly: true
 
10763
}, {
 
10764
    name: "selectright",
 
10765
    bindKey: bindKey("Shift-Right", "Shift-Right"),
 
10766
    exec: function(editor) { editor.getSelection().selectRight(); },
 
10767
    multiSelectAction: "forEach",
 
10768
    readOnly: true
 
10769
}, {
 
10770
    name: "gotoright",
 
10771
    bindKey: bindKey("Right", "Right|Ctrl-F"),
 
10772
    exec: function(editor, args) { editor.navigateRight(args.times); },
 
10773
    multiSelectAction: "forEach",
 
10774
    readOnly: true
 
10775
}, {
 
10776
    name: "selectpagedown",
 
10777
    bindKey: "Shift-PageDown",
 
10778
    exec: function(editor) { editor.selectPageDown(); },
 
10779
    readOnly: true
 
10780
}, {
 
10781
    name: "pagedown",
 
10782
    bindKey: bindKey(null, "Option-PageDown"),
 
10783
    exec: function(editor) { editor.scrollPageDown(); },
 
10784
    readOnly: true
 
10785
}, {
 
10786
    name: "gotopagedown",
 
10787
    bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
 
10788
    exec: function(editor) { editor.gotoPageDown(); },
 
10789
    readOnly: true
 
10790
}, {
 
10791
    name: "selectpageup",
 
10792
    bindKey: "Shift-PageUp",
 
10793
    exec: function(editor) { editor.selectPageUp(); },
 
10794
    readOnly: true
 
10795
}, {
 
10796
    name: "pageup",
 
10797
    bindKey: bindKey(null, "Option-PageUp"),
 
10798
    exec: function(editor) { editor.scrollPageUp(); },
 
10799
    readOnly: true
 
10800
}, {
 
10801
    name: "gotopageup",
 
10802
    bindKey: "PageUp",
 
10803
    exec: function(editor) { editor.gotoPageUp(); },
 
10804
    readOnly: true
 
10805
}, {
 
10806
    name: "scrollup",
 
10807
    bindKey: bindKey("Ctrl-Up", null),
 
10808
    exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
 
10809
    readOnly: true
 
10810
}, {
 
10811
    name: "scrolldown",
 
10812
    bindKey: bindKey("Ctrl-Down", null),
 
10813
    exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
 
10814
    readOnly: true
 
10815
}, {
 
10816
    name: "selectlinestart",
 
10817
    bindKey: "Shift-Home",
 
10818
    exec: function(editor) { editor.getSelection().selectLineStart(); },
 
10819
    multiSelectAction: "forEach",
 
10820
    readOnly: true
 
10821
}, {
 
10822
    name: "selectlineend",
 
10823
    bindKey: "Shift-End",
 
10824
    exec: function(editor) { editor.getSelection().selectLineEnd(); },
 
10825
    multiSelectAction: "forEach",
 
10826
    readOnly: true
 
10827
}, {
 
10828
    name: "togglerecording",
 
10829
    bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
 
10830
    exec: function(editor) { editor.commands.toggleRecording(editor); },
 
10831
    readOnly: true
 
10832
}, {
 
10833
    name: "replaymacro",
 
10834
    bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
 
10835
    exec: function(editor) { editor.commands.replay(editor); },
 
10836
    readOnly: true
 
10837
}, {
 
10838
    name: "jumptomatching",
 
10839
    bindKey: bindKey("Ctrl-P", "Ctrl-Shift-P"),
 
10840
    exec: function(editor) { editor.jumpToMatching(); },
 
10841
    multiSelectAction: "forEach",
 
10842
    readOnly: true
 
10843
}, {
 
10844
    name: "selecttomatching",
 
10845
    bindKey: bindKey("Ctrl-Shift-P", null),
 
10846
    exec: function(editor) { editor.jumpToMatching(true); },
 
10847
    multiSelectAction: "forEach",
 
10848
    readOnly: true
 
10849
}, 
 
10850
{
 
10851
    name: "cut",
 
10852
    exec: function(editor) {
 
10853
        var range = editor.getSelectionRange();
 
10854
        editor._emit("cut", range);
 
10855
 
 
10856
        if (!editor.selection.isEmpty()) {
 
10857
            editor.session.remove(range);
 
10858
            editor.clearSelection();
 
10859
        }
 
10860
    },
 
10861
    multiSelectAction: "forEach"
 
10862
}, {
 
10863
    name: "removeline",
 
10864
    bindKey: bindKey("Ctrl-D", "Command-D"),
 
10865
    exec: function(editor) { editor.removeLines(); },
 
10866
    multiSelectAction: "forEachLine"
 
10867
}, {
 
10868
    name: "duplicateSelection",
 
10869
    bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
 
10870
    exec: function(editor) { editor.duplicateSelection(); },
 
10871
    multiSelectAction: "forEach"
 
10872
}, {
 
10873
    name: "sortlines",
 
10874
    bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
 
10875
    exec: function(editor) { editor.sortLines(); },
 
10876
    multiSelectAction: "forEachLine"
 
10877
}, {
 
10878
    name: "togglecomment",
 
10879
    bindKey: bindKey("Ctrl-/", "Command-/"),
 
10880
    exec: function(editor) { editor.toggleCommentLines(); },
 
10881
    multiSelectAction: "forEachLine"
 
10882
}, {
 
10883
    name: "modifyNumberUp",
 
10884
    bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
 
10885
    exec: function(editor) { editor.modifyNumber(1); },
 
10886
    multiSelectAction: "forEach"
 
10887
}, {
 
10888
    name: "modifyNumberDown",
 
10889
    bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
 
10890
    exec: function(editor) { editor.modifyNumber(-1); },
 
10891
    multiSelectAction: "forEach"
 
10892
}, {
 
10893
    name: "replace",
 
10894
    bindKey: bindKey("Ctrl-H", "Command-Option-F"),
 
10895
    exec: function(editor) {
 
10896
        config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)});
 
10897
    }
 
10898
}, {
 
10899
    name: "undo",
 
10900
    bindKey: bindKey("Ctrl-Z", "Command-Z"),
 
10901
    exec: function(editor) { editor.undo(); }
 
10902
}, {
 
10903
    name: "redo",
 
10904
    bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
 
10905
    exec: function(editor) { editor.redo(); }
 
10906
}, {
 
10907
    name: "copylinesup",
 
10908
    bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
 
10909
    exec: function(editor) { editor.copyLinesUp(); }
 
10910
}, {
 
10911
    name: "movelinesup",
 
10912
    bindKey: bindKey("Alt-Up", "Option-Up"),
 
10913
    exec: function(editor) { editor.moveLinesUp(); }
 
10914
}, {
 
10915
    name: "copylinesdown",
 
10916
    bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
 
10917
    exec: function(editor) { editor.copyLinesDown(); }
 
10918
}, {
 
10919
    name: "movelinesdown",
 
10920
    bindKey: bindKey("Alt-Down", "Option-Down"),
 
10921
    exec: function(editor) { editor.moveLinesDown(); }
 
10922
}, {
 
10923
    name: "del",
 
10924
    bindKey: bindKey("Delete", "Delete|Ctrl-D"),
 
10925
    exec: function(editor) { editor.remove("right"); },
 
10926
    multiSelectAction: "forEach"
 
10927
}, {
 
10928
    name: "backspace",
 
10929
    bindKey: bindKey(
 
10930
        "Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
 
10931
        "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H"
 
10932
    ),
 
10933
    exec: function(editor) { editor.remove("left"); },
 
10934
    multiSelectAction: "forEach"
 
10935
}, {
 
10936
    name: "removetolinestart",
 
10937
    bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
 
10938
    exec: function(editor) { editor.removeToLineStart(); },
 
10939
    multiSelectAction: "forEach"
 
10940
}, {
 
10941
    name: "removetolineend",
 
10942
    bindKey: bindKey("Alt-Delete", "Ctrl-K"),
 
10943
    exec: function(editor) { editor.removeToLineEnd(); },
 
10944
    multiSelectAction: "forEach"
 
10945
}, {
 
10946
    name: "removewordleft",
 
10947
    bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
 
10948
    exec: function(editor) { editor.removeWordLeft(); },
 
10949
    multiSelectAction: "forEach"
 
10950
}, {
 
10951
    name: "removewordright",
 
10952
    bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
 
10953
    exec: function(editor) { editor.removeWordRight(); },
 
10954
    multiSelectAction: "forEach"
 
10955
}, {
 
10956
    name: "outdent",
 
10957
    bindKey: bindKey("Shift-Tab", "Shift-Tab"),
 
10958
    exec: function(editor) { editor.blockOutdent(); },
 
10959
    multiSelectAction: "forEach"
 
10960
}, {
 
10961
    name: "indent",
 
10962
    bindKey: bindKey("Tab", "Tab"),
 
10963
    exec: function(editor) { editor.indent(); },
 
10964
    multiSelectAction: "forEach"
 
10965
},{
 
10966
    name: "blockoutdent",
 
10967
    bindKey: bindKey("Ctrl-[", "Ctrl-["),
 
10968
    exec: function(editor) { editor.blockOutdent(); },
 
10969
    multiSelectAction: "forEachLine"
 
10970
},{
 
10971
    name: "blockindent",
 
10972
    bindKey: bindKey("Ctrl-]", "Ctrl-]"),
 
10973
    exec: function(editor) { editor.blockIndent(); },
 
10974
    multiSelectAction: "forEachLine"
 
10975
}, {
 
10976
    name: "insertstring",
 
10977
    exec: function(editor, str) { editor.insert(str); },
 
10978
    multiSelectAction: "forEach"
 
10979
}, {
 
10980
    name: "inserttext",
 
10981
    exec: function(editor, args) {
 
10982
        editor.insert(lang.stringRepeat(args.text  || "", args.times || 1));
 
10983
    },
 
10984
    multiSelectAction: "forEach"
 
10985
}, {
 
10986
    name: "splitline",
 
10987
    bindKey: bindKey(null, "Ctrl-O"),
 
10988
    exec: function(editor) { editor.splitLine(); },
 
10989
    multiSelectAction: "forEach"
 
10990
}, {
 
10991
    name: "transposeletters",
 
10992
    bindKey: bindKey("Ctrl-T", "Ctrl-T"),
 
10993
    exec: function(editor) { editor.transposeLetters(); },
 
10994
    multiSelectAction: function(editor) {editor.transposeSelections(1); }
 
10995
}, {
 
10996
    name: "touppercase",
 
10997
    bindKey: bindKey("Ctrl-U", "Ctrl-U"),
 
10998
    exec: function(editor) { editor.toUpperCase(); },
 
10999
    multiSelectAction: "forEach"
 
11000
}, {
 
11001
    name: "tolowercase",
 
11002
    bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
 
11003
    exec: function(editor) { editor.toLowerCase(); },
 
11004
    multiSelectAction: "forEach"
 
11005
}];
 
11006
 
 
11007
});
 
11008
 
 
11009
define('ace/undomanager', ['require', 'exports', 'module' ], function(require, exports, module) {
 
11010
var UndoManager = function() {
 
11011
    this.reset();
 
11012
};
 
11013
 
 
11014
(function() {
 
11015
    this.execute = function(options) {
 
11016
        var deltas = options.args[0];
 
11017
        this.$doc  = options.args[1];
 
11018
        this.$undoStack.push(deltas);
 
11019
        this.$redoStack = [];
 
11020
    };
 
11021
    this.undo = function(dontSelect) {
 
11022
        var deltas = this.$undoStack.pop();
 
11023
        var undoSelectionRange = null;
 
11024
        if (deltas) {
 
11025
            undoSelectionRange =
 
11026
                this.$doc.undoChanges(deltas, dontSelect);
 
11027
            this.$redoStack.push(deltas);
 
11028
        }
 
11029
        return undoSelectionRange;
 
11030
    };
 
11031
    this.redo = function(dontSelect) {
 
11032
        var deltas = this.$redoStack.pop();
 
11033
        var redoSelectionRange = null;
 
11034
        if (deltas) {
 
11035
            redoSelectionRange =
 
11036
                this.$doc.redoChanges(deltas, dontSelect);
 
11037
            this.$undoStack.push(deltas);
 
11038
        }
 
11039
        return redoSelectionRange;
 
11040
    };
 
11041
    this.reset = function() {
 
11042
        this.$undoStack = [];
 
11043
        this.$redoStack = [];
 
11044
    };
 
11045
    this.hasUndo = function() {
 
11046
        return this.$undoStack.length > 0;
 
11047
    };
 
11048
    this.hasRedo = function() {
 
11049
        return this.$redoStack.length > 0;
 
11050
    };
 
11051
 
 
11052
}).call(UndoManager.prototype);
 
11053
 
 
11054
exports.UndoManager = UndoManager;
 
11055
});
 
11056
 
 
11057
define('ace/virtual_renderer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent', 'ace/config', 'ace/layer/gutter', 'ace/layer/marker', 'ace/layer/text', 'ace/layer/cursor', 'ace/scrollbar', 'ace/renderloop', 'ace/lib/event_emitter'], function(require, exports, module) {
 
11058
 
 
11059
 
 
11060
var oop = require("./lib/oop");
 
11061
var dom = require("./lib/dom");
 
11062
var event = require("./lib/event");
 
11063
var useragent = require("./lib/useragent");
 
11064
var config = require("./config");
 
11065
var GutterLayer = require("./layer/gutter").Gutter;
 
11066
var MarkerLayer = require("./layer/marker").Marker;
 
11067
var TextLayer = require("./layer/text").Text;
 
11068
var CursorLayer = require("./layer/cursor").Cursor;
 
11069
var ScrollBar = require("./scrollbar").ScrollBar;
 
11070
var RenderLoop = require("./renderloop").RenderLoop;
 
11071
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
11072
var editorCss = ".ace_editor {\
 
11073
position: relative;\
 
11074
overflow: hidden;\
 
11075
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\
 
11076
font-size: 12px;\
 
11077
line-height: normal;\
 
11078
}\
 
11079
.ace_scroller {\
 
11080
position: absolute;\
 
11081
overflow: hidden;\
 
11082
top: 0;\
 
11083
bottom: 0;\
 
11084
}\
 
11085
.ace_content {\
 
11086
position: absolute;\
 
11087
-moz-box-sizing: border-box;\
 
11088
-webkit-box-sizing: border-box;\
 
11089
box-sizing: border-box;\
 
11090
cursor: text;\
 
11091
}\
 
11092
.ace_gutter {\
 
11093
position: absolute;\
 
11094
overflow : hidden;\
 
11095
width: auto;\
 
11096
top: 0;\
 
11097
bottom: 0;\
 
11098
left: 0;\
 
11099
cursor: default;\
 
11100
z-index: 4;\
 
11101
}\
 
11102
.ace_gutter-active-line {\
 
11103
position: absolute;\
 
11104
left: 0;\
 
11105
right: 0;\
 
11106
}\
 
11107
.ace_scroller.ace_scroll-left {\
 
11108
box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\
 
11109
}\
 
11110
.ace_gutter-cell {\
 
11111
padding-left: 19px;\
 
11112
padding-right: 6px;\
 
11113
background-repeat: no-repeat;\
 
11114
}\
 
11115
.ace_gutter-cell.ace_error {\
 
11116
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUM2OEZDQTQ4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUM2OEZDQTU4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQzY4RkNBMjhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQzY4RkNBMzhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkgXxbAAAAJbSURBVHjapFNNaBNBFH4zs5vdZLP5sQmNpT82QY209heh1ioWisaDRcSKF0WKJ0GQnrzrxasHsR6EnlrwD0TagxJabaVEpFYxLWlLSS822tr87m66ccfd2GKyVhA6MMybgfe97/vmPUQphd0sZjto9XIn9OOsvlu2nkqRzVU+6vvlzPf8W6bk8dxQ0NPbxAALgCgg2JkaQuhzQau/El0zbmUA7U0Es8v2CiYmKQJHGO1QICCLoqilMhkmurDAyapKgqItezi/USRdJqEYY4D5jCy03ht2yMkkvL91jTTX10qzyyu2hruPRN7jgbH+EOsXcMLgYiThEgAMhABW85oqy1DXdRIdvP1AHJ2acQXvDIrVHcdQNrEKNYSVMSZGMjEzIIAwDXIo+6G/FxcGnzkC3T2oMhLjre49sBB+RRcHLqdafK6sYdE/GGBwU1VpFNj0aN8pJbe+BkZyevUrvLl6Xmm0W9IuTc0DxrDNAJd5oEvI/KRsNC3bQyNjPO9yQ1YHcfj2QvfQc/5TUhJTBc2iM0U7AWDQtc1nJHvD/cfO2s7jaGkiTEfa/Ep8coLu7zmNmh8+dc5lZDuUeFAGUNA/OY6JVaypQ0vjr7XYjUvJM37vt+j1vuTK5DgVfVUoTjVe+y3/LxMxY2GgU+CSLy4cpfsYorRXuXIOi0Vt40h67uZFTdIo6nLaZcwUJWAzwNS0tBnqqKzQDnjdG/iPyZxo46HaKUpbvYkj8qYRTZsBhge+JHhZyh0x9b95JqjVJkT084kZIPwu/mPWqPgfQ5jXh2+92Ay7HedfAgwA6KDWafb4w3cAAAAASUVORK5CYII=\");\
 
11117
background-repeat: no-repeat;\
 
11118
background-position: 2px center;\
 
11119
}\
 
11120
.ace_gutter-cell.ace_warning {\
 
11121
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUM2OEZDQTg4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUM2OEZDQTk4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQzY4RkNBNjhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQzY4RkNBNzhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pgd7PfIAAAGmSURBVHjaYvr//z8DJZiJgUIANoCRkREb9gLiSVAaQx4OQM7AAkwd7XU2/v++/rOttdYGEB9dASEvOMydGKfH8Gv/p4XTkvRBfLxeQAP+1cUhXopyvzhP7P/IoSj7g7Mw09cNKO6J1QQ0L4gICPIv/veg/8W+JdFvQNLHVsW9/nmn9zk7B+cCkDwhL7gt6knSZnx9/LuCEOcvkIAMP+cvto9nfqyZmmUAksfnBUtbM60gX/3/kgyv3/xSFOL5DZT+L8vP+Yfh5cvfPvp/xUHyQHXGyAYwgpwBjZYFT3Y1OEl/OfCH4ffv3wzc4iwMvNIsDJ+f/mH4+vIPAxsb631WW0Yln6ZpQLXdMK/DXGDflh+sIv37EivD5x//Gb7+YWT4y86sl7BCCkSD+Z++/1dkvsFRl+HnD1Rvje4F8whjMXmGj58YGf5zsDMwcnAwfPvKcml62DsQDeaDxN+/Y0qwlpEHqrdB94IRNIDUgfgfKJChGK4OikEW3gTiXUB950ASLFAF54AC94A0G9QAfOnmF9DCDzABFqS08IHYDIScdijOjQABBgC+/9awBH96jwAAAABJRU5ErkJggg==\");\
 
11122
background-position: 2px center;\
 
11123
}\
 
11124
.ace_gutter-cell.ace_info {\
 
11125
background-image: url(\"data:image/gif;base64,R0lGODlhEAAQAMQAAAAAAEFBQVJSUl5eXmRkZGtra39/f4WFhYmJiZGRkaampry8vMPDw8zMzNXV1dzc3OTk5Orq6vDw8P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABQALAAAAAAQABAAAAUuICWOZGmeaBml5XGwFCQSBGyXRSAwtqQIiRuiwIM5BoYVbEFIyGCQoeJGrVptIQA7\");\
 
11126
background-position: 2px center;\
 
11127
}\
 
11128
.ace_dark .ace_gutter-cell.ace_info {\
 
11129
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRTk5MTVGREIxNDkxMUUxOTc5Q0FFREQyMTNGMjBFQyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRTk5MTVGRUIxNDkxMUUxOTc5Q0FFREQyMTNGMjBFQyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkZFOTkxNUZCQjE0OTExRTE5NzlDQUVERDIxM0YyMEVDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkZFOTkxNUZDQjE0OTExRTE5NzlDQUVERDIxM0YyMEVDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+SIDkjAAAAJ1JREFUeNpi/P//PwMlgImBQkB7A6qrq/+DMC55FkIGKCoq4pVnpFkgTp069f/+/fv/r1u37r+tre1/kg0A+ptn9uzZYLaRkRHpLvjw4cNXWVlZhufPnzOcO3eOdAO0tbVPAjHDmzdvGA4fPsxIsgGSkpJmv379Ynj37h2DjIyMCMkG3LhxQ/T27dsMampqDHZ2dq/pH41DxwCAAAMAFdc68dUsFZgAAAAASUVORK5CYII=\");\
 
11130
}\
 
11131
.ace_scrollbar {\
 
11132
position: absolute;\
 
11133
overflow-x: hidden;\
 
11134
overflow-y: scroll;\
 
11135
right: 0;\
 
11136
top: 0;\
 
11137
bottom: 0;\
 
11138
}\
 
11139
.ace_scrollbar-inner {\
 
11140
position: absolute;\
 
11141
width: 1px;\
 
11142
left: 0;\
 
11143
}\
 
11144
.ace_print-margin {\
 
11145
position: absolute;\
 
11146
height: 100%;\
 
11147
}\
 
11148
.ace_text-input {\
 
11149
position: absolute;\
 
11150
z-index: 0;\
 
11151
width: 0.5em;\
 
11152
height: 1em;\
 
11153
opacity: 0;\
 
11154
background: transparent;\
 
11155
-moz-appearance: none;\
 
11156
appearance: none;\
 
11157
border: none;\
 
11158
resize: none;\
 
11159
outline: none;\
 
11160
overflow: hidden;\
 
11161
font: inherit;\
 
11162
}\
 
11163
.ace_text-input.ace_composition {\
 
11164
background: #f8f8f8;\
 
11165
color: #111;\
 
11166
z-index: 1000;\
 
11167
opacity: 1;\
 
11168
border: solid lightgray 1px;\
 
11169
margin: -1px;\
 
11170
padding: 0 1px;\
 
11171
}\
 
11172
.ace_layer {\
 
11173
z-index: 1;\
 
11174
position: absolute;\
 
11175
overflow: hidden;\
 
11176
white-space: nowrap;\
 
11177
height: 100%;\
 
11178
width: 100%;\
 
11179
-moz-box-sizing: border-box;\
 
11180
-webkit-box-sizing: border-box;\
 
11181
box-sizing: border-box;\
 
11182
/* setting pointer-events: auto; on node under the mouse, which changes\
 
11183
during scroll, will break mouse wheel scrolling in Safari */\
 
11184
pointer-events: none;\
 
11185
}\
 
11186
.ace_gutter-layer {\
 
11187
position: relative;\
 
11188
width: auto;\
 
11189
text-align: right;\
 
11190
pointer-events: auto;\
 
11191
}\
 
11192
.ace_text-layer {\
 
11193
color: black;\
 
11194
font: inherit !important;\
 
11195
}\
 
11196
.ace_cjk {\
 
11197
display: inline-block;\
 
11198
text-align: center;\
 
11199
}\
 
11200
.ace_cursor-layer {\
 
11201
z-index: 4;\
 
11202
}\
 
11203
.ace_cursor {\
 
11204
z-index: 4;\
 
11205
position: absolute;\
 
11206
-moz-box-sizing: border-box;\
 
11207
-webkit-box-sizing: border-box;\
 
11208
box-sizing: border-box;\
 
11209
}\
 
11210
.ace_hidden-cursors .ace_cursor {\
 
11211
opacity: 0.2;\
 
11212
}\
 
11213
.ace_smooth-blinking .ace_cursor {\
 
11214
-moz-transition: opacity 0.18s;\
 
11215
-webkit-transition: opacity 0.18s;\
 
11216
-o-transition: opacity 0.18s;\
 
11217
-ms-transition: opacity 0.18s;\
 
11218
transition: opacity 0.18s;\
 
11219
}\
 
11220
.ace_cursor[style*=\"opacity: 0\"]{\
 
11221
-ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";\
 
11222
}\
 
11223
.ace_editor.ace_multiselect .ace_cursor {\
 
11224
border-left-width: 1px;\
 
11225
}\
 
11226
.ace_line {\
 
11227
white-space: nowrap;\
 
11228
}\
 
11229
.ace_marker-layer .ace_step {\
 
11230
position: absolute;\
 
11231
z-index: 3;\
 
11232
}\
 
11233
.ace_marker-layer .ace_selection {\
 
11234
position: absolute;\
 
11235
z-index: 5;\
 
11236
}\
 
11237
.ace_marker-layer .ace_bracket {\
 
11238
position: absolute;\
 
11239
z-index: 6;\
 
11240
}\
 
11241
.ace_marker-layer .ace_active-line {\
 
11242
position: absolute;\
 
11243
z-index: 2;\
 
11244
}\
 
11245
.ace_marker-layer .ace_selected-word {\
 
11246
position: absolute;\
 
11247
z-index: 4;\
 
11248
-moz-box-sizing: border-box;\
 
11249
-webkit-box-sizing: border-box;\
 
11250
box-sizing: border-box;\
 
11251
}\
 
11252
.ace_line .ace_fold {\
 
11253
-moz-box-sizing: border-box;\
 
11254
-webkit-box-sizing: border-box;\
 
11255
box-sizing: border-box;\
 
11256
display: inline-block;\
 
11257
height: 11px;\
 
11258
margin-top: -2px;\
 
11259
vertical-align: middle;\
 
11260
background-image:\
 
11261
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\
 
11262
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%3AIDAT8%11c%FC%FF%FF%7F%18%03%1A%60%01%F2%3F%A0%891%80%04%FF%11-%F8%17%9BJ%E2%05%B1ZD%81v%26t%E7%80%F8%A3%82h%A12%1A%20%A3%01%02%0F%01%BA%25%06%00%19%C0%0D%AEF%D5%3ES%00%00%00%00IEND%AEB%60%82\");\
 
11263
background-repeat: no-repeat, repeat-x;\
 
11264
background-position: center center, top left;\
 
11265
color: transparent;\
 
11266
border: 1px solid black;\
 
11267
-moz-border-radius: 2px;\
 
11268
-webkit-border-radius: 2px;\
 
11269
border-radius: 2px;\
 
11270
cursor: pointer;\
 
11271
pointer-events: auto;\
 
11272
}\
 
11273
.ace_dark .ace_fold {\
 
11274
}\
 
11275
.ace_fold:hover{\
 
11276
background-image:\
 
11277
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\
 
11278
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%003IDAT8%11c%FC%FF%FF%7F%3E%03%1A%60%01%F2%3F%A3%891%80%04%FFQ%26%F8w%C0%B43%A1%DB%0C%E2%8F%0A%A2%85%CAh%80%8C%06%08%3C%04%E8%96%18%00%A3S%0D%CD%CF%D8%C1%9D%00%00%00%00IEND%AEB%60%82\");\
 
11279
background-repeat: no-repeat, repeat-x;\
 
11280
background-position: center center, top left;\
 
11281
}\
 
11282
.ace_editor.ace_dragging .ace_content {\
 
11283
cursor: move;\
 
11284
}\
 
11285
.ace_gutter-tooltip {\
 
11286
background-color: #FFF;\
 
11287
background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\
 
11288
background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\
 
11289
border: 1px solid gray;\
 
11290
border-radius: 1px;\
 
11291
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\
 
11292
color: black;\
 
11293
display: inline-block;\
 
11294
max-width: 500px;\
 
11295
padding: 4px;\
 
11296
position: fixed;\
 
11297
z-index: 300;\
 
11298
-moz-box-sizing: border-box;\
 
11299
-webkit-box-sizing: border-box;\
 
11300
box-sizing: border-box;\
 
11301
cursor: default;\
 
11302
white-space: pre-line;\
 
11303
word-wrap: break-word;\
 
11304
line-height: normal;\
 
11305
font-style: normal;\
 
11306
font-weight: normal;\
 
11307
letter-spacing: normal;\
 
11308
}\
 
11309
.ace_folding-enabled > .ace_gutter-cell {\
 
11310
padding-right: 13px;\
 
11311
}\
 
11312
.ace_fold-widget {\
 
11313
-moz-box-sizing: border-box;\
 
11314
-webkit-box-sizing: border-box;\
 
11315
box-sizing: border-box;\
 
11316
margin: 0 -12px 0 1px;\
 
11317
display: inline-block;\
 
11318
width: 11px;\
 
11319
vertical-align: top;\
 
11320
background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAe%8A%B1%0D%000%0C%C2%F2%2CK%96%BC%D0%8F9%81%88H%E9%D0%0E%96%C0%10%92%3E%02%80%5E%82%E4%A9*-%EEsw%C8%CC%11%EE%96w%D8%DC%E9*Eh%0C%151(%00%00%00%00IEND%AEB%60%82\");\
 
11321
background-repeat: no-repeat;\
 
11322
background-position: center;\
 
11323
border-radius: 3px;\
 
11324
border: 1px solid transparent;\
 
11325
}\
 
11326
.ace_fold-widget.ace_end {\
 
11327
background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAm%C7%C1%09%000%08C%D1%8C%ECE%C8E(%8E%EC%02)%1EZJ%F1%C1'%04%07I%E1%E5%EE%CAL%F5%A2%99%99%22%E2%D6%1FU%B5%FE0%D9x%A7%26Wz5%0E%D5%00%00%00%00IEND%AEB%60%82\");\
 
11328
}\
 
11329
.ace_fold-widget.ace_closed {\
 
11330
background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%03%00%00%00%06%08%06%00%00%00%06%E5%24%0C%00%00%009IDATx%DA5%CA%C1%09%000%08%03%C0%AC*(%3E%04%C1%0D%BA%B1%23%A4Uh%E0%20%81%C0%CC%F8%82%81%AA%A2%AArGfr%88%08%11%11%1C%DD%7D%E0%EE%5B%F6%F6%CB%B8%05Q%2F%E9tai%D9%00%00%00%00IEND%AEB%60%82\");\
 
11331
}\
 
11332
.ace_fold-widget:hover {\
 
11333
border: 1px solid rgba(0, 0, 0, 0.3);\
 
11334
background-color: rgba(255, 255, 255, 0.2);\
 
11335
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
 
11336
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
 
11337
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
 
11338
}\
 
11339
.ace_fold-widget:active {\
 
11340
border: 1px solid rgba(0, 0, 0, 0.4);\
 
11341
background-color: rgba(0, 0, 0, 0.05);\
 
11342
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
 
11343
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
 
11344
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
 
11345
}\
 
11346
/**\
 
11347
* Dark version for fold widgets\
 
11348
*/\
 
11349
.ace_dark .ace_fold-widget {\
 
11350
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\
 
11351
}\
 
11352
.ace_dark .ace_fold-widget.ace_end {\
 
11353
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\
 
11354
}\
 
11355
.ace_dark .ace_fold-widget.ace_closed {\
 
11356
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\
 
11357
}\
 
11358
.ace_dark .ace_fold-widget:hover {\
 
11359
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
 
11360
background-color: rgba(255, 255, 255, 0.1);\
 
11361
}\
 
11362
.ace_dark .ace_fold-widget:active {\
 
11363
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
 
11364
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
 
11365
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
 
11366
}\
 
11367
.ace_fold-widget.ace_invalid {\
 
11368
background-color: #FFB4B4;\
 
11369
border-color: #DE5555;\
 
11370
}\
 
11371
.ace_fade-fold-widgets .ace_fold-widget {\
 
11372
-moz-transition: opacity 0.4s ease 0.05s;\
 
11373
-webkit-transition: opacity 0.4s ease 0.05s;\
 
11374
-o-transition: opacity 0.4s ease 0.05s;\
 
11375
-ms-transition: opacity 0.4s ease 0.05s;\
 
11376
transition: opacity 0.4s ease 0.05s;\
 
11377
opacity: 0;\
 
11378
}\
 
11379
.ace_fade-fold-widgets:hover .ace_fold-widget {\
 
11380
-moz-transition: opacity 0.05s ease 0.05s;\
 
11381
-webkit-transition: opacity 0.05s ease 0.05s;\
 
11382
-o-transition: opacity 0.05s ease 0.05s;\
 
11383
-ms-transition: opacity 0.05s ease 0.05s;\
 
11384
transition: opacity 0.05s ease 0.05s;\
 
11385
opacity:1;\
 
11386
}\
 
11387
.ace_underline {\
 
11388
text-decoration: underline;\
 
11389
}\
 
11390
.ace_bold {\
 
11391
font-weight: bold;\
 
11392
}\
 
11393
.ace_nobold .ace_bold {\
 
11394
font-weight: normal;\
 
11395
}\
 
11396
.ace_italic {\
 
11397
font-style: italic;\
 
11398
}\
 
11399
";
 
11400
 
 
11401
dom.importCssString(editorCss, "ace_editor");
 
11402
 
 
11403
var VirtualRenderer = function(container, theme) {
 
11404
    var _self = this;
 
11405
 
 
11406
    this.container = container || dom.createElement("div");
 
11407
    this.$keepTextAreaAtCursor = !useragent.isIE;
 
11408
 
 
11409
    dom.addCssClass(this.container, "ace_editor");
 
11410
 
 
11411
    this.setTheme(theme);
 
11412
 
 
11413
    this.$gutter = dom.createElement("div");
 
11414
    this.$gutter.className = "ace_gutter";
 
11415
    this.container.appendChild(this.$gutter);
 
11416
 
 
11417
    this.scroller = dom.createElement("div");
 
11418
    this.scroller.className = "ace_scroller";
 
11419
    this.container.appendChild(this.scroller);
 
11420
 
 
11421
    this.content = dom.createElement("div");
 
11422
    this.content.className = "ace_content";
 
11423
    this.scroller.appendChild(this.content);
 
11424
 
 
11425
    this.$gutterLayer = new GutterLayer(this.$gutter);
 
11426
    this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this));
 
11427
 
 
11428
    this.$markerBack = new MarkerLayer(this.content);
 
11429
 
 
11430
    var textLayer = this.$textLayer = new TextLayer(this.content);
 
11431
    this.canvas = textLayer.element;
 
11432
 
 
11433
    this.$markerFront = new MarkerLayer(this.content);
 
11434
 
 
11435
    this.$cursorLayer = new CursorLayer(this.content);
 
11436
    this.$horizScroll = false;
 
11437
    this.$horizScrollAlwaysVisible = false;
 
11438
 
 
11439
    this.scrollBar = new ScrollBar(this.container);
 
11440
    this.scrollBar.addEventListener("scroll", function(e) {
 
11441
        if (!_self.$inScrollAnimation)
 
11442
            _self.session.setScrollTop(e.data);
 
11443
    });
 
11444
 
 
11445
    this.scrollTop = 0;
 
11446
    this.scrollLeft = 0;
 
11447
 
 
11448
    event.addListener(this.scroller, "scroll", function() {
 
11449
        var scrollLeft = _self.scroller.scrollLeft;
 
11450
        _self.scrollLeft = scrollLeft;
 
11451
        _self.session.setScrollLeft(scrollLeft);
 
11452
    });
 
11453
 
 
11454
    this.cursorPos = {
 
11455
        row : 0,
 
11456
        column : 0
 
11457
    };
 
11458
 
 
11459
    this.$textLayer.addEventListener("changeCharacterSize", function() {
 
11460
        _self.updateCharacterSize();
 
11461
        _self.onResize(true);
 
11462
    });
 
11463
 
 
11464
    this.$size = {
 
11465
        width: 0,
 
11466
        height: 0,
 
11467
        scrollerHeight: 0,
 
11468
        scrollerWidth: 0
 
11469
    };
 
11470
 
 
11471
    this.layerConfig = {
 
11472
        width : 1,
 
11473
        padding : 0,
 
11474
        firstRow : 0,
 
11475
        firstRowScreen: 0,
 
11476
        lastRow : 0,
 
11477
        lineHeight : 1,
 
11478
        characterWidth : 1,
 
11479
        minHeight : 1,
 
11480
        maxHeight : 1,
 
11481
        offset : 0,
 
11482
        height : 1
 
11483
    };
 
11484
 
 
11485
    this.$loop = new RenderLoop(
 
11486
        this.$renderChanges.bind(this),
 
11487
        this.container.ownerDocument.defaultView
 
11488
    );
 
11489
    this.$loop.schedule(this.CHANGE_FULL);
 
11490
 
 
11491
    this.updateCharacterSize();
 
11492
    this.setPadding(4);
 
11493
    config.resetOptions(this);
 
11494
    config._emit("renderer", this);
 
11495
};
 
11496
 
 
11497
(function() {
 
11498
 
 
11499
    this.CHANGE_CURSOR = 1;
 
11500
    this.CHANGE_MARKER = 2;
 
11501
    this.CHANGE_GUTTER = 4;
 
11502
    this.CHANGE_SCROLL = 8;
 
11503
    this.CHANGE_LINES = 16;
 
11504
    this.CHANGE_TEXT = 32;
 
11505
    this.CHANGE_SIZE = 64;
 
11506
    this.CHANGE_MARKER_BACK = 128;
 
11507
    this.CHANGE_MARKER_FRONT = 256;
 
11508
    this.CHANGE_FULL = 512;
 
11509
    this.CHANGE_H_SCROLL = 1024;
 
11510
 
 
11511
    oop.implement(this, EventEmitter);
 
11512
 
 
11513
    this.updateCharacterSize = function() {
 
11514
        if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {
 
11515
            this.$allowBoldFonts = this.$textLayer.allowBoldFonts;
 
11516
            this.setStyle("ace_nobold", !this.$allowBoldFonts);
 
11517
        }
 
11518
 
 
11519
        this.characterWidth = this.$textLayer.getCharacterWidth();
 
11520
        this.lineHeight = this.$textLayer.getLineHeight();
 
11521
        this.$updatePrintMargin();
 
11522
    };
 
11523
    this.setSession = function(session) {
 
11524
        this.session = session;
 
11525
 
 
11526
        this.scroller.className = "ace_scroller";
 
11527
 
 
11528
        this.$cursorLayer.setSession(session);
 
11529
        this.$markerBack.setSession(session);
 
11530
        this.$markerFront.setSession(session);
 
11531
        this.$gutterLayer.setSession(session);
 
11532
        this.$textLayer.setSession(session);
 
11533
        this.$loop.schedule(this.CHANGE_FULL);
 
11534
 
 
11535
    };
 
11536
    this.updateLines = function(firstRow, lastRow) {
 
11537
        if (lastRow === undefined)
 
11538
            lastRow = Infinity;
 
11539
 
 
11540
        if (!this.$changedLines) {
 
11541
            this.$changedLines = {
 
11542
                firstRow: firstRow,
 
11543
                lastRow: lastRow
 
11544
            };
 
11545
        }
 
11546
        else {
 
11547
            if (this.$changedLines.firstRow > firstRow)
 
11548
                this.$changedLines.firstRow = firstRow;
 
11549
 
 
11550
            if (this.$changedLines.lastRow < lastRow)
 
11551
                this.$changedLines.lastRow = lastRow;
 
11552
        }
 
11553
 
 
11554
        if (this.$changedLines.firstRow > this.layerConfig.lastRow ||
 
11555
            this.$changedLines.lastRow < this.layerConfig.firstRow)
 
11556
            return;
 
11557
        this.$loop.schedule(this.CHANGE_LINES);
 
11558
    };
 
11559
 
 
11560
    this.onChangeTabSize = function() {
 
11561
        this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);
 
11562
        this.$textLayer.onChangeTabSize();
 
11563
    };
 
11564
    this.updateText = function() {
 
11565
        this.$loop.schedule(this.CHANGE_TEXT);
 
11566
    };
 
11567
    this.updateFull = function(force) {
 
11568
        if (force)
 
11569
            this.$renderChanges(this.CHANGE_FULL, true);
 
11570
        else
 
11571
            this.$loop.schedule(this.CHANGE_FULL);
 
11572
    };
 
11573
    this.updateFontSize = function() {
 
11574
        this.$textLayer.checkForSizeChanges();
 
11575
    };
 
11576
    this.onResize = function(force, gutterWidth, width, height) {
 
11577
        var changes = 0;
 
11578
        var size = this.$size;
 
11579
 
 
11580
        if (this.resizing > 2)
 
11581
            return;
 
11582
        else if (this.resizing > 1)
 
11583
            this.resizing++;
 
11584
        else
 
11585
            this.resizing = force ? 1 : 0;
 
11586
        if (!height)
 
11587
            height = dom.getInnerHeight(this.container);
 
11588
 
 
11589
        if (height && (force || size.height != height)) {
 
11590
            size.height = height;
 
11591
            changes = this.CHANGE_SIZE;
 
11592
 
 
11593
            size.scrollerHeight = this.scroller.clientHeight;
 
11594
            if (!size.scrollerHeight) {
 
11595
                size.scrollerHeight = size.height;
 
11596
                if (this.$horizScroll)
 
11597
                    size.scrollerHeight -= this.scrollBar.getWidth();
 
11598
            }
 
11599
            this.scrollBar.setHeight(size.scrollerHeight);
 
11600
 
 
11601
            if (this.session) {
 
11602
                this.session.setScrollTop(this.getScrollTop());
 
11603
                changes = changes | this.CHANGE_FULL;
 
11604
            }
 
11605
        }
 
11606
 
 
11607
        if (!width)
 
11608
            width = dom.getInnerWidth(this.container);
 
11609
 
 
11610
        if (width && (force || this.resizing > 1 || size.width != width)) {
 
11611
            changes = this.CHANGE_SIZE;
 
11612
            size.width = width;
 
11613
 
 
11614
            var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
 
11615
            this.scroller.style.left = gutterWidth + "px";
 
11616
            size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
 
11617
            this.scroller.style.right = this.scrollBar.getWidth() + "px";
 
11618
 
 
11619
            if (this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
 
11620
                changes = changes | this.CHANGE_FULL;
 
11621
        }
 
11622
 
 
11623
        if (force)
 
11624
            this.$renderChanges(changes, true);
 
11625
        else
 
11626
            this.$loop.schedule(changes);
 
11627
 
 
11628
        if (force)
 
11629
            this.$gutterLayer.$padding = null;
 
11630
 
 
11631
        if (force)
 
11632
            delete this.resizing;
 
11633
    };
 
11634
 
 
11635
    this.onGutterResize = function() {
 
11636
        var width = this.$size.width;
 
11637
        var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
 
11638
        this.scroller.style.left = gutterWidth + "px";
 
11639
        this.$size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
 
11640
 
 
11641
        if (this.session.getUseWrapMode() && this.adjustWrapLimit())
 
11642
            this.$loop.schedule(this.CHANGE_FULL);
 
11643
    };
 
11644
    this.adjustWrapLimit = function() {
 
11645
        var availableWidth = this.$size.scrollerWidth - this.$padding * 2;
 
11646
        var limit = Math.floor(availableWidth / this.characterWidth);
 
11647
        return this.session.adjustWrapLimit(limit);
 
11648
    };
 
11649
    this.setAnimatedScroll = function(shouldAnimate){
 
11650
        this.setOption("animatedScroll", shouldAnimate);
 
11651
    };
 
11652
    this.getAnimatedScroll = function() {
 
11653
        return this.$animatedScroll;
 
11654
    };
 
11655
    this.setShowInvisibles = function(showInvisibles) {
 
11656
        this.setOption("showInvisibles", showInvisibles);
 
11657
    };
 
11658
    this.getShowInvisibles = function() {
 
11659
        return this.getOption("showInvisibles");
 
11660
    };
 
11661
    this.getDisplayIndentGuides = function() {
 
11662
        return this.getOption("displayIndentGuides");
 
11663
    };
 
11664
 
 
11665
    this.setDisplayIndentGuides = function(display) {
 
11666
        this.setOption("displayIndentGuides", display);
 
11667
    };
 
11668
    this.setShowPrintMargin = function(showPrintMargin) {
 
11669
        this.setOption("showPrintMargin", showPrintMargin);
 
11670
    };
 
11671
    this.getShowPrintMargin = function() {
 
11672
        this.getOption("showPrintMargin");
 
11673
    };
 
11674
    this.setPrintMarginColumn = function(showPrintMargin) {
 
11675
        this.setOption("printMarginColumn", showPrintMargin);
 
11676
    };
 
11677
    this.getPrintMarginColumn = function() {
 
11678
        return this.getOption("printMarginColumn");
 
11679
    };
 
11680
    this.getShowGutter = function(){
 
11681
        return this.getOption("showGutter");
 
11682
    };
 
11683
    this.setShowGutter = function(show){
 
11684
        return this.setOption("showGutter", show);
 
11685
    };
 
11686
 
 
11687
    this.getFadeFoldWidgets = function(){
 
11688
        return this.getOption("fadeFoldWidgets")
 
11689
    };
 
11690
 
 
11691
    this.setFadeFoldWidgets = function(show) {
 
11692
        this.setOption("fadeFoldWidgets", show);
 
11693
    };
 
11694
 
 
11695
    this.setHighlightGutterLine = function(shouldHighlight) {
 
11696
        this.setOption("highlightGutterLine", shouldHighlight);
 
11697
    };
 
11698
 
 
11699
    this.getHighlightGutterLine = function() {
 
11700
        return this.getOption("highlightGutterLine");
 
11701
    };
 
11702
 
 
11703
    this.$updateGutterLineHighlight = function() {
 
11704
        var pos = this.$cursorLayer.$pixelPos;
 
11705
        var height = this.layerConfig.lineHeight;
 
11706
        if (this.session.getUseWrapMode()) {
 
11707
            var cursor = this.session.selection.getCursor();
 
11708
            cursor.column = 0;
 
11709
            pos = this.$cursorLayer.getPixelPosition(cursor, true);
 
11710
            height *= this.session.getRowLength(cursor.row);
 
11711
        }
 
11712
        this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px";
 
11713
        this.$gutterLineHighlight.style.height = height + "px";
 
11714
    };
 
11715
 
 
11716
    this.$updatePrintMargin = function() {
 
11717
        if (!this.$showPrintMargin && !this.$printMarginEl)
 
11718
            return;
 
11719
 
 
11720
        if (!this.$printMarginEl) {
 
11721
            var containerEl = dom.createElement("div");
 
11722
            containerEl.className = "ace_layer ace_print-margin-layer";
 
11723
            this.$printMarginEl = dom.createElement("div");
 
11724
            this.$printMarginEl.className = "ace_print-margin";
 
11725
            containerEl.appendChild(this.$printMarginEl);
 
11726
            this.content.insertBefore(containerEl, this.content.firstChild);
 
11727
        }
 
11728
 
 
11729
        var style = this.$printMarginEl.style;
 
11730
        style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px";
 
11731
        style.visibility = this.$showPrintMargin ? "visible" : "hidden";
 
11732
    };
 
11733
    this.getContainerElement = function() {
 
11734
        return this.container;
 
11735
    };
 
11736
    this.getMouseEventTarget = function() {
 
11737
        return this.content;
 
11738
    };
 
11739
    this.getTextAreaContainer = function() {
 
11740
        return this.container;
 
11741
    };
 
11742
    this.$moveTextAreaToCursor = function() {
 
11743
        if (!this.$keepTextAreaAtCursor)
 
11744
            return;
 
11745
        var config = this.layerConfig;
 
11746
        var posTop = this.$cursorLayer.$pixelPos.top;
 
11747
        var posLeft = this.$cursorLayer.$pixelPos.left;
 
11748
        posTop -= config.offset;
 
11749
 
 
11750
        if (posTop < 0 || posTop > config.height - this.lineHeight)
 
11751
            return;
 
11752
 
 
11753
        var w = this.characterWidth;
 
11754
        if (this.$composition) {
 
11755
            var val = this.textarea.value.replace(/^\x01+/, "");
 
11756
            w *= this.session.$getStringScreenWidth(val)[0];
 
11757
        }
 
11758
        posLeft -= this.scrollLeft;
 
11759
        if (posLeft > this.$size.scrollerWidth - w)
 
11760
            posLeft = this.$size.scrollerWidth - w;
 
11761
 
 
11762
        posLeft -= this.scrollBar.width;
 
11763
 
 
11764
        this.textarea.style.height = this.lineHeight + "px";
 
11765
        this.textarea.style.width = w + "px";
 
11766
        this.textarea.style.right = Math.max(0, this.$size.scrollerWidth - posLeft - w) + "px";
 
11767
        this.textarea.style.bottom = Math.max(0, this.$size.height - posTop - this.lineHeight) + "px";
 
11768
    };
 
11769
    this.getFirstVisibleRow = function() {
 
11770
        return this.layerConfig.firstRow;
 
11771
    };
 
11772
    this.getFirstFullyVisibleRow = function() {
 
11773
        return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);
 
11774
    };
 
11775
    this.getLastFullyVisibleRow = function() {
 
11776
        var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight);
 
11777
        return this.layerConfig.firstRow - 1 + flint;
 
11778
    };
 
11779
    this.getLastVisibleRow = function() {
 
11780
        return this.layerConfig.lastRow;
 
11781
    };
 
11782
 
 
11783
    this.$padding = null;
 
11784
    this.setPadding = function(padding) {
 
11785
        this.$padding = padding;
 
11786
        this.$textLayer.setPadding(padding);
 
11787
        this.$cursorLayer.setPadding(padding);
 
11788
        this.$markerFront.setPadding(padding);
 
11789
        this.$markerBack.setPadding(padding);
 
11790
        this.$loop.schedule(this.CHANGE_FULL);
 
11791
        this.$updatePrintMargin();
 
11792
    };
 
11793
    this.getHScrollBarAlwaysVisible = function() {
 
11794
        return this.$horizScrollAlwaysVisible;
 
11795
    };
 
11796
    this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
 
11797
        if (this.$horizScrollAlwaysVisible != alwaysVisible) {
 
11798
            this.$horizScrollAlwaysVisible = alwaysVisible;
 
11799
            if (!this.$horizScrollAlwaysVisible || !this.$horizScroll)
 
11800
                this.$loop.schedule(this.CHANGE_SCROLL);
 
11801
        }
 
11802
    };
 
11803
 
 
11804
    this.$updateScrollBar = function() {
 
11805
        this.scrollBar.setInnerHeight(this.layerConfig.maxHeight);
 
11806
        this.scrollBar.setScrollTop(this.scrollTop);
 
11807
    };
 
11808
 
 
11809
    this.$renderChanges = function(changes, force) {
 
11810
        if (!force && (!changes || !this.session || !this.container.offsetWidth))
 
11811
            return;
 
11812
 
 
11813
        this._signal("beforeRender");
 
11814
        if (changes & this.CHANGE_FULL ||
 
11815
            changes & this.CHANGE_SIZE ||
 
11816
            changes & this.CHANGE_TEXT ||
 
11817
            changes & this.CHANGE_LINES ||
 
11818
            changes & this.CHANGE_SCROLL
 
11819
        )
 
11820
            this.$computeLayerConfig();
 
11821
        if (changes & this.CHANGE_H_SCROLL) {
 
11822
            this.scroller.scrollLeft = this.scrollLeft;
 
11823
            var scrollLeft = this.scroller.scrollLeft;
 
11824
            this.scrollLeft = scrollLeft;
 
11825
            this.session.setScrollLeft(scrollLeft);
 
11826
 
 
11827
            this.scroller.className = this.scrollLeft == 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
 
11828
        }
 
11829
        if (changes & this.CHANGE_FULL) {
 
11830
            this.$textLayer.checkForSizeChanges();
 
11831
            this.$updateScrollBar();
 
11832
            this.$textLayer.update(this.layerConfig);
 
11833
            if (this.$showGutter)
 
11834
                this.$gutterLayer.update(this.layerConfig);
 
11835
            this.$markerBack.update(this.layerConfig);
 
11836
            this.$markerFront.update(this.layerConfig);
 
11837
            this.$cursorLayer.update(this.layerConfig);
 
11838
            this.$moveTextAreaToCursor();
 
11839
            this.$highlightGutterLine && this.$updateGutterLineHighlight();
 
11840
            this._signal("afterRender");
 
11841
            return;
 
11842
        }
 
11843
        if (changes & this.CHANGE_SCROLL) {
 
11844
            if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
 
11845
                this.$textLayer.update(this.layerConfig);
 
11846
            else
 
11847
                this.$textLayer.scrollLines(this.layerConfig);
 
11848
 
 
11849
            if (this.$showGutter)
 
11850
                this.$gutterLayer.update(this.layerConfig);
 
11851
            this.$markerBack.update(this.layerConfig);
 
11852
            this.$markerFront.update(this.layerConfig);
 
11853
            this.$cursorLayer.update(this.layerConfig);
 
11854
            this.$highlightGutterLine && this.$updateGutterLineHighlight();
 
11855
            this.$moveTextAreaToCursor();
 
11856
            this.$updateScrollBar();
 
11857
            this._signal("afterRender");
 
11858
            return;
 
11859
        }
 
11860
 
 
11861
        if (changes & this.CHANGE_TEXT) {
 
11862
            this.$textLayer.update(this.layerConfig);
 
11863
            if (this.$showGutter)
 
11864
                this.$gutterLayer.update(this.layerConfig);
 
11865
        }
 
11866
        else if (changes & this.CHANGE_LINES) {
 
11867
            if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)
 
11868
                this.$gutterLayer.update(this.layerConfig);
 
11869
        }
 
11870
        else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
 
11871
            if (this.$showGutter)
 
11872
                this.$gutterLayer.update(this.layerConfig);
 
11873
        }
 
11874
 
 
11875
        if (changes & this.CHANGE_CURSOR) {
 
11876
            this.$cursorLayer.update(this.layerConfig);
 
11877
            this.$moveTextAreaToCursor();
 
11878
            this.$highlightGutterLine && this.$updateGutterLineHighlight();
 
11879
        }
 
11880
 
 
11881
        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
 
11882
            this.$markerFront.update(this.layerConfig);
 
11883
        }
 
11884
 
 
11885
        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
 
11886
            this.$markerBack.update(this.layerConfig);
 
11887
        }
 
11888
 
 
11889
        if (changes & this.CHANGE_SIZE)
 
11890
            this.$updateScrollBar();
 
11891
 
 
11892
        this._signal("afterRender");
 
11893
    };
 
11894
 
 
11895
    this.$computeLayerConfig = function() {
 
11896
        if (!this.$size.scrollerHeight)
 
11897
            return this.onResize(true);
 
11898
 
 
11899
        var session = this.session;
 
11900
 
 
11901
        var offset = this.scrollTop % this.lineHeight;
 
11902
        var minHeight = this.$size.scrollerHeight + this.lineHeight;
 
11903
 
 
11904
        var longestLine = this.$getLongestLine();
 
11905
 
 
11906
        var horizScroll = this.$horizScrollAlwaysVisible || this.$size.scrollerWidth - longestLine < 0;
 
11907
        var horizScrollChanged = this.$horizScroll !== horizScroll;
 
11908
        this.$horizScroll = horizScroll;
 
11909
        if (horizScrollChanged) {
 
11910
            this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden";
 
11911
            if (!horizScroll)
 
11912
                this.session.setScrollLeft(0);
 
11913
        }
 
11914
        var maxHeight = this.session.getScreenLength() * this.lineHeight;
 
11915
        this.session.setScrollTop(Math.max(0, Math.min(this.scrollTop, maxHeight - this.$size.scrollerHeight)));
 
11916
 
 
11917
        var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
 
11918
        var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
 
11919
        var lastRow = firstRow + lineCount;
 
11920
        var firstRowScreen, firstRowHeight;
 
11921
        var lineHeight = this.lineHeight;
 
11922
        firstRow = session.screenToDocumentRow(firstRow, 0);
 
11923
        var foldLine = session.getFoldLine(firstRow);
 
11924
        if (foldLine) {
 
11925
            firstRow = foldLine.start.row;
 
11926
        }
 
11927
 
 
11928
        firstRowScreen = session.documentToScreenRow(firstRow, 0);
 
11929
        firstRowHeight = session.getRowLength(firstRow) * lineHeight;
 
11930
 
 
11931
        lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);
 
11932
        minHeight = this.$size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +
 
11933
                                                firstRowHeight;
 
11934
 
 
11935
        offset = this.scrollTop - firstRowScreen * lineHeight;
 
11936
 
 
11937
        this.layerConfig = {
 
11938
            width : longestLine,
 
11939
            padding : this.$padding,
 
11940
            firstRow : firstRow,
 
11941
            firstRowScreen: firstRowScreen,
 
11942
            lastRow : lastRow,
 
11943
            lineHeight : lineHeight,
 
11944
            characterWidth : this.characterWidth,
 
11945
            minHeight : minHeight,
 
11946
            maxHeight : maxHeight,
 
11947
            offset : offset,
 
11948
            height : this.$size.scrollerHeight
 
11949
        };
 
11950
 
 
11951
        this.$gutterLayer.element.style.marginTop = (-offset) + "px";
 
11952
        this.content.style.marginTop = (-offset) + "px";
 
11953
        this.content.style.width = longestLine + 2 * this.$padding + "px";
 
11954
        this.content.style.height = minHeight + "px";
 
11955
        if (horizScrollChanged)
 
11956
            this.onResize(true);
 
11957
    };
 
11958
 
 
11959
    this.$updateLines = function() {
 
11960
        var firstRow = this.$changedLines.firstRow;
 
11961
        var lastRow = this.$changedLines.lastRow;
 
11962
        this.$changedLines = null;
 
11963
 
 
11964
        var layerConfig = this.layerConfig;
 
11965
 
 
11966
        if (firstRow > layerConfig.lastRow + 1) { return; }
 
11967
        if (lastRow < layerConfig.firstRow) { return; }
 
11968
        if (lastRow === Infinity) {
 
11969
            if (this.$showGutter)
 
11970
                this.$gutterLayer.update(layerConfig);
 
11971
            this.$textLayer.update(layerConfig);
 
11972
            return;
 
11973
        }
 
11974
        this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
 
11975
        return true;
 
11976
    };
 
11977
 
 
11978
    this.$getLongestLine = function() {
 
11979
        var charCount = this.session.getScreenWidth();
 
11980
        if (this.$textLayer.showInvisibles)
 
11981
            charCount += 1;
 
11982
 
 
11983
        return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));
 
11984
    };
 
11985
    this.updateFrontMarkers = function() {
 
11986
        this.$markerFront.setMarkers(this.session.getMarkers(true));
 
11987
        this.$loop.schedule(this.CHANGE_MARKER_FRONT);
 
11988
    };
 
11989
    this.updateBackMarkers = function() {
 
11990
        this.$markerBack.setMarkers(this.session.getMarkers());
 
11991
        this.$loop.schedule(this.CHANGE_MARKER_BACK);
 
11992
    };
 
11993
    this.addGutterDecoration = function(row, className){
 
11994
        this.$gutterLayer.addGutterDecoration(row, className);
 
11995
    };
 
11996
    this.removeGutterDecoration = function(row, className){
 
11997
        this.$gutterLayer.removeGutterDecoration(row, className);
 
11998
    };
 
11999
    this.updateBreakpoints = function(rows) {
 
12000
        this.$loop.schedule(this.CHANGE_GUTTER);
 
12001
    };
 
12002
    this.setAnnotations = function(annotations) {
 
12003
        this.$gutterLayer.setAnnotations(annotations);
 
12004
        this.$loop.schedule(this.CHANGE_GUTTER);
 
12005
    };
 
12006
    this.updateCursor = function() {
 
12007
        this.$loop.schedule(this.CHANGE_CURSOR);
 
12008
    };
 
12009
    this.hideCursor = function() {
 
12010
        this.$cursorLayer.hideCursor();
 
12011
    };
 
12012
    this.showCursor = function() {
 
12013
        this.$cursorLayer.showCursor();
 
12014
    };
 
12015
 
 
12016
    this.scrollSelectionIntoView = function(anchor, lead, offset) {
 
12017
        this.scrollCursorIntoView(anchor, offset);
 
12018
        this.scrollCursorIntoView(lead, offset);
 
12019
    };
 
12020
    this.scrollCursorIntoView = function(cursor, offset) {
 
12021
        if (this.$size.scrollerHeight === 0)
 
12022
            return;
 
12023
 
 
12024
        var pos = this.$cursorLayer.getPixelPosition(cursor);
 
12025
 
 
12026
        var left = pos.left;
 
12027
        var top = pos.top;
 
12028
 
 
12029
        if (this.scrollTop > top) {
 
12030
            if (offset)
 
12031
                top -= offset * this.$size.scrollerHeight;
 
12032
            this.session.setScrollTop(top);
 
12033
        } else if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
 
12034
            if (offset)
 
12035
                top += offset * this.$size.scrollerHeight;
 
12036
            this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
 
12037
        }
 
12038
 
 
12039
        var scrollLeft = this.scrollLeft;
 
12040
 
 
12041
        if (scrollLeft > left) {
 
12042
            if (left < this.$padding + 2 * this.layerConfig.characterWidth)
 
12043
                left = 0;
 
12044
            this.session.setScrollLeft(left);
 
12045
        } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
 
12046
            this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
 
12047
        }
 
12048
    };
 
12049
    this.getScrollTop = function() {
 
12050
        return this.session.getScrollTop();
 
12051
    };
 
12052
    this.getScrollLeft = function() {
 
12053
        return this.session.getScrollLeft();
 
12054
    };
 
12055
    this.getScrollTopRow = function() {
 
12056
        return this.scrollTop / this.lineHeight;
 
12057
    };
 
12058
    this.getScrollBottomRow = function() {
 
12059
        return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);
 
12060
    };
 
12061
    this.scrollToRow = function(row) {
 
12062
        this.session.setScrollTop(row * this.lineHeight);
 
12063
    };
 
12064
 
 
12065
    this.alignCursor = function(cursor, alignment) {
 
12066
        if (typeof cursor == "number")
 
12067
            cursor = {row: cursor, column: 0};
 
12068
 
 
12069
        var pos = this.$cursorLayer.getPixelPosition(cursor);
 
12070
        var h = this.$size.scrollerHeight - this.lineHeight;
 
12071
        var offset = pos.top - h * (alignment || 0);
 
12072
 
 
12073
        this.session.setScrollTop(offset);
 
12074
        return offset;
 
12075
    };
 
12076
 
 
12077
    this.STEPS = 8;
 
12078
    this.$calcSteps = function(fromValue, toValue){
 
12079
        var i = 0;
 
12080
        var l = this.STEPS;
 
12081
        var steps = [];
 
12082
 
 
12083
        var func  = function(t, x_min, dx) {
 
12084
            return dx * (Math.pow(t - 1, 3) + 1) + x_min;
 
12085
        };
 
12086
 
 
12087
        for (i = 0; i < l; ++i)
 
12088
            steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
 
12089
 
 
12090
        return steps;
 
12091
    };
 
12092
    this.scrollToLine = function(line, center, animate, callback) {
 
12093
        var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});
 
12094
        var offset = pos.top;
 
12095
        if (center)
 
12096
            offset -= this.$size.scrollerHeight / 2;
 
12097
 
 
12098
        var initialScroll = this.scrollTop;
 
12099
        this.session.setScrollTop(offset);
 
12100
        if (animate !== false)
 
12101
            this.animateScrolling(initialScroll, callback);
 
12102
    };
 
12103
 
 
12104
    this.animateScrolling = function(fromValue, callback) {
 
12105
        var toValue = this.scrollTop;
 
12106
        if (this.$animatedScroll && Math.abs(fromValue - toValue) < 100000) {
 
12107
            var _self = this;
 
12108
            var steps = _self.$calcSteps(fromValue, toValue);
 
12109
            this.$inScrollAnimation = true;
 
12110
 
 
12111
            clearInterval(this.$timer);
 
12112
 
 
12113
            _self.session.setScrollTop(steps.shift());
 
12114
            this.$timer = setInterval(function() {
 
12115
                if (steps.length) {
 
12116
                    _self.session.setScrollTop(steps.shift());
 
12117
                    _self.session.$scrollTop = toValue;
 
12118
                } else if (toValue != null) {
 
12119
                    _self.session.$scrollTop = -1;
 
12120
                    _self.session.setScrollTop(toValue);
 
12121
                    toValue = null;
 
12122
                } else {
 
12123
                    _self.$timer = clearInterval(_self.$timer);
 
12124
                    _self.$inScrollAnimation = false;
 
12125
                    callback && callback();
 
12126
                }
 
12127
            }, 10);
 
12128
        }
 
12129
    };
 
12130
    this.scrollToY = function(scrollTop) {
 
12131
        if (this.scrollTop !== scrollTop) {
 
12132
            this.$loop.schedule(this.CHANGE_SCROLL);
 
12133
            this.scrollTop = scrollTop;
 
12134
        }
 
12135
    };
 
12136
    this.scrollToX = function(scrollLeft) {
 
12137
        if (scrollLeft < 0)
 
12138
            scrollLeft = 0;
 
12139
 
 
12140
        if (this.scrollLeft !== scrollLeft)
 
12141
            this.scrollLeft = scrollLeft;
 
12142
        this.$loop.schedule(this.CHANGE_H_SCROLL);
 
12143
    };
 
12144
    this.scrollBy = function(deltaX, deltaY) {
 
12145
        deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);
 
12146
        deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);
 
12147
    };
 
12148
    this.isScrollableBy = function(deltaX, deltaY) {
 
12149
        if (deltaY < 0 && this.session.getScrollTop() >= 1)
 
12150
           return true;
 
12151
        if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight - this.layerConfig.maxHeight < -1)
 
12152
           return true;
 
12153
    };
 
12154
 
 
12155
    this.pixelToScreenCoordinates = function(x, y) {
 
12156
        var canvasPos = this.scroller.getBoundingClientRect();
 
12157
 
 
12158
        var offset = (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth;
 
12159
        var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);
 
12160
        var col = Math.round(offset);
 
12161
 
 
12162
        return {row: row, column: col, side: offset - col > 0 ? 1 : -1};
 
12163
    };
 
12164
 
 
12165
    this.screenToTextCoordinates = function(x, y) {
 
12166
        var canvasPos = this.scroller.getBoundingClientRect();
 
12167
 
 
12168
        var col = Math.round(
 
12169
            (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth
 
12170
        );
 
12171
        var row = Math.floor(
 
12172
            (y + this.scrollTop - canvasPos.top) / this.lineHeight
 
12173
        );
 
12174
 
 
12175
        return this.session.screenToDocumentPosition(row, Math.max(col, 0));
 
12176
    };
 
12177
    this.textToScreenCoordinates = function(row, column) {
 
12178
        var canvasPos = this.scroller.getBoundingClientRect();
 
12179
        var pos = this.session.documentToScreenPosition(row, column);
 
12180
 
 
12181
        var x = this.$padding + Math.round(pos.column * this.characterWidth);
 
12182
        var y = pos.row * this.lineHeight;
 
12183
 
 
12184
        return {
 
12185
            pageX: canvasPos.left + x - this.scrollLeft,
 
12186
            pageY: canvasPos.top + y - this.scrollTop
 
12187
        };
 
12188
    };
 
12189
    this.visualizeFocus = function() {
 
12190
        dom.addCssClass(this.container, "ace_focus");
 
12191
    };
 
12192
    this.visualizeBlur = function() {
 
12193
        dom.removeCssClass(this.container, "ace_focus");
 
12194
    };
 
12195
    this.showComposition = function(position) {
 
12196
        if (!this.$composition)
 
12197
            this.$composition = {
 
12198
                keepTextAreaAtCursor: this.$keepTextAreaAtCursor,
 
12199
                cssText: this.textarea.style.cssText
 
12200
            };
 
12201
 
 
12202
        this.$keepTextAreaAtCursor = true;
 
12203
        dom.addCssClass(this.textarea, "ace_composition");
 
12204
        this.textarea.style.cssText = "";
 
12205
        this.$moveTextAreaToCursor();
 
12206
    };
 
12207
    this.setCompositionText = function(text) {
 
12208
        this.$moveTextAreaToCursor();
 
12209
    };
 
12210
    this.hideComposition = function() {
 
12211
        if (!this.$composition)
 
12212
            return;
 
12213
 
 
12214
        dom.removeCssClass(this.textarea, "ace_composition");
 
12215
        this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor;
 
12216
        this.textarea.style.cssText = this.$composition.cssText;
 
12217
        this.$composition = null;
 
12218
    };
 
12219
    this.setTheme = function(theme) {
 
12220
        var _self = this;
 
12221
        this.$themeValue = theme;
 
12222
        _self._dispatchEvent('themeChange',{theme:theme});
 
12223
 
 
12224
        if (!theme || typeof theme == "string") {
 
12225
            var moduleName = theme || "ace/theme/textmate";
 
12226
            config.loadModule(["theme", moduleName], afterLoad);
 
12227
        } else {
 
12228
            afterLoad(theme);
 
12229
        }
 
12230
 
 
12231
        function afterLoad(theme) {
 
12232
            dom.importCssString(
 
12233
                theme.cssText,
 
12234
                theme.cssClass,
 
12235
                _self.container.ownerDocument
 
12236
            );
 
12237
 
 
12238
            if (_self.theme)
 
12239
                dom.removeCssClass(_self.container, _self.theme.cssClass);
 
12240
            _self.$theme = theme.cssClass;
 
12241
 
 
12242
            _self.theme = theme;
 
12243
            dom.addCssClass(_self.container, theme.cssClass);
 
12244
            dom.setCssClass(_self.container, "ace_dark", theme.isDark);
 
12245
 
 
12246
            var padding = theme.padding || 4;
 
12247
            if (_self.$padding && padding != _self.$padding)
 
12248
                _self.setPadding(padding);
 
12249
            if (_self.$size) {
 
12250
                _self.$size.width = 0;
 
12251
                _self.onResize();
 
12252
            }
 
12253
 
 
12254
            _self._dispatchEvent('themeLoaded',{theme:theme});
 
12255
        }
 
12256
    };
 
12257
    this.getTheme = function() {
 
12258
        return this.$themeValue;
 
12259
    };
 
12260
    this.setStyle = function setStyle(style, include) {
 
12261
        dom.setCssClass(this.container, style, include != false);
 
12262
    };
 
12263
    this.unsetStyle = function unsetStyle(style) {
 
12264
        dom.removeCssClass(this.container, style);
 
12265
    };
 
12266
    this.destroy = function() {
 
12267
        this.$textLayer.destroy();
 
12268
        this.$cursorLayer.destroy();
 
12269
    };
 
12270
 
 
12271
}).call(VirtualRenderer.prototype);
 
12272
 
 
12273
 
 
12274
config.defineOptions(VirtualRenderer.prototype, "renderer", {
 
12275
    animatedScroll: {initialValue: false},
 
12276
    showInvisibles: {
 
12277
        set: function(value) {
 
12278
            if (this.$textLayer.setShowInvisibles(value))
 
12279
                this.$loop.schedule(this.CHANGE_TEXT);
 
12280
        },
 
12281
        initialValue: false
 
12282
    },
 
12283
    showPrintMargin: {
 
12284
        set: function() { this.$updatePrintMargin(); },
 
12285
        initialValue: true
 
12286
    },
 
12287
    printMarginColumn: {
 
12288
        set: function() { this.$updatePrintMargin(); },
 
12289
        initialValue: 80
 
12290
    },
 
12291
    showGutter: {
 
12292
        set: function(show){
 
12293
            this.$gutter.style.display = show ? "block" : "none";
 
12294
            this.onGutterResize();
 
12295
        },
 
12296
        initialValue: true
 
12297
    },
 
12298
    fadeFoldWidgets: {
 
12299
        set: function(show) {
 
12300
            dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show);
 
12301
        },
 
12302
        initialValue: false
 
12303
    },
 
12304
    showFoldWidgets: {
 
12305
        set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)},
 
12306
        initialValue: true
 
12307
    },
 
12308
    displayIndentGuides: {
 
12309
        set: function(show) {
 
12310
            if (this.$textLayer.setDisplayIndentGuides(show))
 
12311
                this.$loop.schedule(this.CHANGE_TEXT);
 
12312
        },
 
12313
        initialValue: true
 
12314
    },
 
12315
    highlightGutterLine: {
 
12316
        set: function(shouldHighlight) {
 
12317
            if (!this.$gutterLineHighlight) {
 
12318
                this.$gutterLineHighlight = dom.createElement("div");
 
12319
                this.$gutterLineHighlight.className = "ace_gutter-active-line";
 
12320
                this.$gutter.appendChild(this.$gutterLineHighlight);
 
12321
                return;
 
12322
            }
 
12323
 
 
12324
            this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
 
12325
            if (this.$cursorLayer.$pixelPos)
 
12326
                this.$updateGutterLineHighlight();
 
12327
        },
 
12328
        initialValue: false,
 
12329
        value: true
 
12330
    }
 
12331
});
 
12332
 
 
12333
exports.VirtualRenderer = VirtualRenderer;
 
12334
});
 
12335
 
 
12336
define('ace/layer/gutter', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter'], function(require, exports, module) {
 
12337
 
 
12338
 
 
12339
var dom = require("../lib/dom");
 
12340
var oop = require("../lib/oop");
 
12341
var lang = require("../lib/lang");
 
12342
var EventEmitter = require("../lib/event_emitter").EventEmitter;
 
12343
 
 
12344
var Gutter = function(parentEl) {
 
12345
    this.element = dom.createElement("div");
 
12346
    this.element.className = "ace_layer ace_gutter-layer";
 
12347
    parentEl.appendChild(this.element);
 
12348
    this.setShowFoldWidgets(this.$showFoldWidgets);
 
12349
    
 
12350
    this.gutterWidth = 0;
 
12351
 
 
12352
    this.$annotations = [];
 
12353
    this.$updateAnnotations = this.$updateAnnotations.bind(this);
 
12354
};
 
12355
 
 
12356
(function() {
 
12357
 
 
12358
    oop.implement(this, EventEmitter);
 
12359
 
 
12360
    this.setSession = function(session) {
 
12361
        if (this.session)
 
12362
            this.session.removeEventListener("change", this.$updateAnnotations);
 
12363
        this.session = session;
 
12364
        session.on("change", this.$updateAnnotations);
 
12365
    };
 
12366
 
 
12367
    this.addGutterDecoration = function(row, className){
 
12368
        if (window.console)
 
12369
            console.warn && console.warn("deprecated use session.addGutterDecoration");
 
12370
        this.session.addGutterDecoration(row, className);
 
12371
    };
 
12372
 
 
12373
    this.removeGutterDecoration = function(row, className){
 
12374
        if (window.console)
 
12375
            console.warn && console.warn("deprecated use session.removeGutterDecoration");
 
12376
        this.session.removeGutterDecoration(row, className);
 
12377
    };
 
12378
 
 
12379
    this.setAnnotations = function(annotations) {
 
12380
        this.$annotations = []
 
12381
        var rowInfo, row;
 
12382
        for (var i = 0; i < annotations.length; i++) {
 
12383
            var annotation = annotations[i];
 
12384
            var row = annotation.row;
 
12385
            var rowInfo = this.$annotations[row];
 
12386
            if (!rowInfo)
 
12387
                rowInfo = this.$annotations[row] = {text: []};
 
12388
           
 
12389
            var annoText = annotation.text;
 
12390
            annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || "";
 
12391
 
 
12392
            if (rowInfo.text.indexOf(annoText) === -1)
 
12393
                rowInfo.text.push(annoText);
 
12394
 
 
12395
            var type = annotation.type;
 
12396
            if (type == "error")
 
12397
                rowInfo.className = " ace_error";
 
12398
            else if (type == "warning" && rowInfo.className != " ace_error")
 
12399
                rowInfo.className = " ace_warning";
 
12400
            else if (type == "info" && (!rowInfo.className))
 
12401
                rowInfo.className = " ace_info";
 
12402
        }
 
12403
    };
 
12404
 
 
12405
    this.$updateAnnotations = function (e) {
 
12406
        if (!this.$annotations.length)
 
12407
            return;
 
12408
        var delta = e.data;
 
12409
        var range = delta.range;
 
12410
        var firstRow = range.start.row;
 
12411
        var len = range.end.row - firstRow;
 
12412
        if (len === 0) {
 
12413
        } else if (delta.action == "removeText" || delta.action == "removeLines") {
 
12414
            this.$annotations.splice(firstRow, len + 1, null);
 
12415
        } else {
 
12416
            var args = Array(len + 1);
 
12417
            args.unshift(firstRow, 1);
 
12418
            this.$annotations.splice.apply(this.$annotations, args);
 
12419
        }
 
12420
    };
 
12421
 
 
12422
    this.update = function(config) {
 
12423
        var emptyAnno = {className: ""};
 
12424
        var html = [];
 
12425
        var i = config.firstRow;
 
12426
        var lastRow = config.lastRow;
 
12427
        var fold = this.session.getNextFoldLine(i);
 
12428
        var foldStart = fold ? fold.start.row : Infinity;
 
12429
        var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets;
 
12430
        var breakpoints = this.session.$breakpoints;
 
12431
        var decorations = this.session.$decorations;
 
12432
        var firstLineNumber = this.session.$firstLineNumber;
 
12433
        var lastLineNumber = 0;
 
12434
 
 
12435
        while (true) {
 
12436
            if(i > foldStart) {
 
12437
                i = fold.end.row + 1;
 
12438
                fold = this.session.getNextFoldLine(i, fold);
 
12439
                foldStart = fold ?fold.start.row :Infinity;
 
12440
            }
 
12441
            if(i > lastRow)
 
12442
                break;
 
12443
 
 
12444
            var annotation = this.$annotations[i] || emptyAnno;
 
12445
            html.push(
 
12446
                "<div class='ace_gutter-cell ",
 
12447
                breakpoints[i] || "", decorations[i] || "", annotation.className,
 
12448
                "' style='height:", this.session.getRowLength(i) * config.lineHeight, "px;'>", 
 
12449
                lastLineNumber = i + firstLineNumber
 
12450
            );
 
12451
 
 
12452
            if (foldWidgets) {
 
12453
                var c = foldWidgets[i];
 
12454
                if (c == null)
 
12455
                    c = foldWidgets[i] = this.session.getFoldWidget(i);
 
12456
                if (c)
 
12457
                    html.push(
 
12458
                        "<span class='ace_fold-widget ace_", c,
 
12459
                        c == "start" && i == foldStart && i < fold.end.row ? " ace_closed" : " ace_open",
 
12460
                        "' style='height:", config.lineHeight, "px",
 
12461
                        "'></span>"
 
12462
                    );
 
12463
            }
 
12464
 
 
12465
            html.push("</div>");
 
12466
 
 
12467
            i++;
 
12468
        }
 
12469
 
 
12470
        this.element = dom.setInnerHtml(this.element, html.join(""));
 
12471
        this.element.style.height = config.minHeight + "px";
 
12472
        
 
12473
        if (this.session.$useWrapMode)
 
12474
            lastLineNumber = this.session.getLength();
 
12475
        
 
12476
        var gutterWidth = ("" + lastLineNumber).length * config.characterWidth;
 
12477
        var padding = this.$padding || this.$computePadding();
 
12478
        gutterWidth += padding.left + padding.right;
 
12479
        if (gutterWidth !== this.gutterWidth) {
 
12480
            this.gutterWidth = gutterWidth;
 
12481
            this.element.style.width = Math.ceil(this.gutterWidth) + "px";
 
12482
            this._emit("changeGutterWidth", gutterWidth);
 
12483
        }
 
12484
    };
 
12485
 
 
12486
    this.$showFoldWidgets = true;
 
12487
    this.setShowFoldWidgets = function(show) {
 
12488
        if (show)
 
12489
            dom.addCssClass(this.element, "ace_folding-enabled");
 
12490
        else
 
12491
            dom.removeCssClass(this.element, "ace_folding-enabled");
 
12492
 
 
12493
        this.$showFoldWidgets = show;
 
12494
        this.$padding = null;
 
12495
    };
 
12496
    
 
12497
    this.getShowFoldWidgets = function() {
 
12498
        return this.$showFoldWidgets;
 
12499
    };
 
12500
 
 
12501
    this.$computePadding = function() {
 
12502
        if (!this.element.firstChild)
 
12503
            return {left: 0, right: 0};
 
12504
        var style = dom.computedStyle(this.element.firstChild);
 
12505
        this.$padding = {}
 
12506
        this.$padding.left = parseInt(style.paddingLeft) + 1;
 
12507
        this.$padding.right = parseInt(style.paddingRight);  
 
12508
        return this.$padding;
 
12509
    };
 
12510
 
 
12511
    this.getRegion = function(point) {
 
12512
        var padding = this.$padding || this.$computePadding();
 
12513
        var rect = this.element.getBoundingClientRect();
 
12514
        if (point.x < padding.left + rect.left)
 
12515
            return "markers";
 
12516
        if (this.$showFoldWidgets && point.x > rect.right - padding.right)
 
12517
            return "foldWidgets";
 
12518
    };
 
12519
 
 
12520
}).call(Gutter.prototype);
 
12521
 
 
12522
exports.Gutter = Gutter;
 
12523
 
 
12524
});
 
12525
 
 
12526
define('ace/layer/marker', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/dom'], function(require, exports, module) {
 
12527
 
 
12528
 
 
12529
var Range = require("../range").Range;
 
12530
var dom = require("../lib/dom");
 
12531
 
 
12532
var Marker = function(parentEl) {
 
12533
    this.element = dom.createElement("div");
 
12534
    this.element.className = "ace_layer ace_marker-layer";
 
12535
    parentEl.appendChild(this.element);
 
12536
};
 
12537
 
 
12538
(function() {
 
12539
 
 
12540
    this.$padding = 0;
 
12541
 
 
12542
    this.setPadding = function(padding) {
 
12543
        this.$padding = padding;
 
12544
    };
 
12545
    this.setSession = function(session) {
 
12546
        this.session = session;
 
12547
    };
 
12548
    
 
12549
    this.setMarkers = function(markers) {
 
12550
        this.markers = markers;
 
12551
    };
 
12552
 
 
12553
    this.update = function(config) {
 
12554
        var config = config || this.config;
 
12555
        if (!config)
 
12556
            return;
 
12557
 
 
12558
        this.config = config;
 
12559
 
 
12560
 
 
12561
        var html = [];
 
12562
        for (var key in this.markers) {
 
12563
            var marker = this.markers[key];
 
12564
 
 
12565
            if (!marker.range) {
 
12566
                marker.update(html, this, this.session, config);
 
12567
                continue;
 
12568
            }
 
12569
 
 
12570
            var range = marker.range.clipRows(config.firstRow, config.lastRow);
 
12571
            if (range.isEmpty()) continue;
 
12572
 
 
12573
            range = range.toScreenRange(this.session);
 
12574
            if (marker.renderer) {
 
12575
                var top = this.$getTop(range.start.row, config);
 
12576
                var left = this.$padding + range.start.column * config.characterWidth;
 
12577
                marker.renderer(html, range, left, top, config);
 
12578
            } else if (marker.type == "fullLine") {
 
12579
                this.drawFullLineMarker(html, range, marker.clazz, config);
 
12580
            } else if (marker.type == "screenLine") {
 
12581
                this.drawScreenLineMarker(html, range, marker.clazz, config);
 
12582
            } else if (range.isMultiLine()) {
 
12583
                if (marker.type == "text")
 
12584
                    this.drawTextMarker(html, range, marker.clazz, config);
 
12585
                else
 
12586
                    this.drawMultiLineMarker(html, range, marker.clazz, config);
 
12587
            } else {
 
12588
                this.drawSingleLineMarker(html, range, marker.clazz + " ace_start", config);
 
12589
            }
 
12590
        }
 
12591
        this.element = dom.setInnerHtml(this.element, html.join(""));
 
12592
    };
 
12593
 
 
12594
    this.$getTop = function(row, layerConfig) {
 
12595
        return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
 
12596
    };
 
12597
    this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
 
12598
        var row = range.start.row;
 
12599
 
 
12600
        var lineRange = new Range(
 
12601
            row, range.start.column,
 
12602
            row, this.session.getScreenLastRowColumn(row)
 
12603
        );
 
12604
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz + " ace_start", layerConfig, 1, "text");
 
12605
        row = range.end.row;
 
12606
        lineRange = new Range(row, 0, row, range.end.column);
 
12607
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 0, "text");
 
12608
 
 
12609
        for (row = range.start.row + 1; row < range.end.row; row++) {
 
12610
            lineRange.start.row = row;
 
12611
            lineRange.end.row = row;
 
12612
            lineRange.end.column = this.session.getScreenLastRowColumn(row);
 
12613
            this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1, "text");
 
12614
        }
 
12615
    };
 
12616
    this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, type) {
 
12617
        var padding = this.$padding;
 
12618
        var height = config.lineHeight;
 
12619
        var top = this.$getTop(range.start.row, config);
 
12620
        var left = padding + range.start.column * config.characterWidth;
 
12621
 
 
12622
        stringBuilder.push(
 
12623
            "<div class='", clazz, " ace_start' style='",
 
12624
            "height:", height, "px;",
 
12625
            "right:0;",
 
12626
            "top:", top, "px;",
 
12627
            "left:", left, "px;'></div>"
 
12628
        );
 
12629
        top = this.$getTop(range.end.row, config);
 
12630
        var width = range.end.column * config.characterWidth;
 
12631
 
 
12632
        stringBuilder.push(
 
12633
            "<div class='", clazz, "' style='",
 
12634
            "height:", height, "px;",
 
12635
            "width:", width, "px;",
 
12636
            "top:", top, "px;",
 
12637
            "left:", padding, "px;'></div>"
 
12638
        );
 
12639
        height = (range.end.row - range.start.row - 1) * config.lineHeight;
 
12640
        if (height < 0)
 
12641
            return;
 
12642
        top = this.$getTop(range.start.row + 1, config);
 
12643
 
 
12644
        stringBuilder.push(
 
12645
            "<div class='", clazz, "' style='",
 
12646
            "height:", height, "px;",
 
12647
            "right:0;",
 
12648
            "top:", top, "px;",
 
12649
            "left:", padding, "px;'></div>"
 
12650
        );
 
12651
    };
 
12652
    this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength) {
 
12653
        var height = config.lineHeight;
 
12654
        var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;
 
12655
 
 
12656
        var top = this.$getTop(range.start.row, config);
 
12657
        var left = this.$padding + range.start.column * config.characterWidth;
 
12658
 
 
12659
        stringBuilder.push(
 
12660
            "<div class='", clazz, "' style='",
 
12661
            "height:", height, "px;",
 
12662
            "width:", width, "px;",
 
12663
            "top:", top, "px;",
 
12664
            "left:", left,"px;'></div>"
 
12665
        );
 
12666
    };
 
12667
 
 
12668
    this.drawFullLineMarker = function(stringBuilder, range, clazz, config) {
 
12669
        var top = this.$getTop(range.start.row, config);
 
12670
        var height = config.lineHeight;
 
12671
        if (range.start.row != range.end.row)
 
12672
            height += this.$getTop(range.end.row, config) - top;
 
12673
 
 
12674
        stringBuilder.push(
 
12675
            "<div class='", clazz, "' style='",
 
12676
            "height:", height, "px;",
 
12677
            "top:", top, "px;",
 
12678
            "left:0;right:0;'></div>"
 
12679
        );
 
12680
    };
 
12681
    
 
12682
    this.drawScreenLineMarker = function(stringBuilder, range, clazz, config) {
 
12683
        var top = this.$getTop(range.start.row, config);
 
12684
        var height = config.lineHeight;
 
12685
 
 
12686
        stringBuilder.push(
 
12687
            "<div class='", clazz, "' style='",
 
12688
            "height:", height, "px;",
 
12689
            "top:", top, "px;",
 
12690
            "left:0;right:0;'></div>"
 
12691
        );
 
12692
    };
 
12693
 
 
12694
}).call(Marker.prototype);
 
12695
 
 
12696
exports.Marker = Marker;
 
12697
 
 
12698
});
 
12699
 
 
12700
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) {
 
12701
 
 
12702
 
 
12703
var oop = require("../lib/oop");
 
12704
var dom = require("../lib/dom");
 
12705
var lang = require("../lib/lang");
 
12706
var useragent = require("../lib/useragent");
 
12707
var EventEmitter = require("../lib/event_emitter").EventEmitter;
 
12708
 
 
12709
var Text = function(parentEl) {
 
12710
    this.element = dom.createElement("div");
 
12711
    this.element.className = "ace_layer ace_text-layer";
 
12712
    parentEl.appendChild(this.element);
 
12713
 
 
12714
    this.$characterSize = {width: 0, height: 0};
 
12715
    this.checkForSizeChanges();
 
12716
    this.$pollSizeChanges();
 
12717
};
 
12718
 
 
12719
(function() {
 
12720
 
 
12721
    oop.implement(this, EventEmitter);
 
12722
 
 
12723
    this.EOF_CHAR = "\xB6"; //"&para;";
 
12724
    this.EOL_CHAR = "\xAC"; //"&not;";
 
12725
    this.TAB_CHAR = "\u2192"; //"&rarr;" "\u21E5";
 
12726
    this.SPACE_CHAR = "\xB7"; //"&middot;";
 
12727
    this.$padding = 0;
 
12728
 
 
12729
    this.setPadding = function(padding) {
 
12730
        this.$padding = padding;
 
12731
        this.element.style.padding = "0 " + padding + "px";
 
12732
    };
 
12733
 
 
12734
    this.getLineHeight = function() {
 
12735
        return this.$characterSize.height || 1;
 
12736
    };
 
12737
 
 
12738
    this.getCharacterWidth = function() {
 
12739
        return this.$characterSize.width || 1;
 
12740
    };
 
12741
 
 
12742
    this.checkForSizeChanges = function() {
 
12743
        var size = this.$measureSizes();
 
12744
        if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
 
12745
            this.$measureNode.style.fontWeight = "bold";
 
12746
            var boldSize = this.$measureSizes();
 
12747
            this.$measureNode.style.fontWeight = "";
 
12748
            this.$characterSize = size;
 
12749
            this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;
 
12750
            this._emit("changeCharacterSize", {data: size});
 
12751
        }
 
12752
    };
 
12753
 
 
12754
    this.$pollSizeChanges = function() {
 
12755
        var self = this;
 
12756
        this.$pollSizeChangesTimer = setInterval(function() {
 
12757
            self.checkForSizeChanges();
 
12758
        }, 500);
 
12759
    };
 
12760
 
 
12761
    this.$fontStyles = {
 
12762
        fontFamily : 1,
 
12763
        fontSize : 1,
 
12764
        fontWeight : 1,
 
12765
        fontStyle : 1,
 
12766
        lineHeight : 1
 
12767
    };
 
12768
 
 
12769
    this.$measureSizes = useragent.isIE || useragent.isOldGecko ? function() {
 
12770
        var n = 1000;
 
12771
        if (!this.$measureNode) {
 
12772
            var measureNode = this.$measureNode = dom.createElement("div");
 
12773
            var style = measureNode.style;
 
12774
 
 
12775
            style.width = style.height = "auto";
 
12776
            style.left = style.top = (-n * 40)  + "px";
 
12777
 
 
12778
            style.visibility = "hidden";
 
12779
            style.position = "fixed";
 
12780
            style.overflow = "visible";
 
12781
            style.whiteSpace = "nowrap";
 
12782
            measureNode.innerHTML = lang.stringRepeat("Xy", n);
 
12783
 
 
12784
            if (this.element.ownerDocument.body) {
 
12785
                this.element.ownerDocument.body.appendChild(measureNode);
 
12786
            } else {
 
12787
                var container = this.element.parentNode;
 
12788
                while (!dom.hasCssClass(container, "ace_editor"))
 
12789
                    container = container.parentNode;
 
12790
                container.appendChild(measureNode);
 
12791
            }
 
12792
        }
 
12793
        if (!this.element.offsetWidth)
 
12794
            return null;
 
12795
 
 
12796
        var style = this.$measureNode.style;
 
12797
        var computedStyle = dom.computedStyle(this.element);
 
12798
        for (var prop in this.$fontStyles)
 
12799
            style[prop] = computedStyle[prop];
 
12800
 
 
12801
        var size = {
 
12802
            height: this.$measureNode.offsetHeight,
 
12803
            width: this.$measureNode.offsetWidth / (n * 2)
 
12804
        };
 
12805
        if (size.width == 0 || size.height == 0)
 
12806
            return null;
 
12807
 
 
12808
        return size;
 
12809
    }
 
12810
    : function() {
 
12811
        if (!this.$measureNode) {
 
12812
            var measureNode = this.$measureNode = dom.createElement("div");
 
12813
            var style = measureNode.style;
 
12814
 
 
12815
            style.width = style.height = "auto";
 
12816
            style.left = style.top = -100 + "px";
 
12817
 
 
12818
            style.visibility = "hidden";
 
12819
            style.position = "fixed";
 
12820
            style.overflow = "visible";
 
12821
            style.whiteSpace = "nowrap";
 
12822
 
 
12823
            measureNode.innerHTML = "X";
 
12824
 
 
12825
            var container = this.element.parentNode;
 
12826
            while (container && !dom.hasCssClass(container, "ace_editor"))
 
12827
                container = container.parentNode;
 
12828
 
 
12829
            if (!container)
 
12830
                return this.$measureNode = null;
 
12831
 
 
12832
            container.appendChild(measureNode);
 
12833
        }
 
12834
 
 
12835
        var rect = this.$measureNode.getBoundingClientRect();
 
12836
 
 
12837
        var size = {
 
12838
            height: rect.height,
 
12839
            width: rect.width
 
12840
        };
 
12841
        if (size.width == 0 || size.height == 0)
 
12842
            return null;
 
12843
 
 
12844
        return size;
 
12845
    };
 
12846
 
 
12847
    this.setSession = function(session) {
 
12848
        this.session = session;
 
12849
        this.$computeTabString();
 
12850
    };
 
12851
 
 
12852
    this.showInvisibles = false;
 
12853
    this.setShowInvisibles = function(showInvisibles) {
 
12854
        if (this.showInvisibles == showInvisibles)
 
12855
            return false;
 
12856
 
 
12857
        this.showInvisibles = showInvisibles;
 
12858
        this.$computeTabString();
 
12859
        return true;
 
12860
    };
 
12861
 
 
12862
    this.displayIndentGuides = true;
 
12863
    this.setDisplayIndentGuides = function(display) {
 
12864
        if (this.displayIndentGuides == display)
 
12865
            return false;
 
12866
 
 
12867
        this.displayIndentGuides = display;
 
12868
        this.$computeTabString();
 
12869
        return true;
 
12870
    };
 
12871
 
 
12872
    this.$tabStrings = [];
 
12873
    this.onChangeTabSize =
 
12874
    this.$computeTabString = function() {
 
12875
        var tabSize = this.session.getTabSize();
 
12876
        this.tabSize = tabSize;
 
12877
        var tabStr = this.$tabStrings = [0];
 
12878
        for (var i = 1; i < tabSize + 1; i++) {
 
12879
            if (this.showInvisibles) {
 
12880
                tabStr.push("<span class='ace_invisible'>"
 
12881
                    + this.TAB_CHAR
 
12882
                    + lang.stringRepeat("\xa0", i - 1)
 
12883
                    + "</span>");
 
12884
            } else {
 
12885
                tabStr.push(lang.stringRepeat("\xa0", i));
 
12886
            }
 
12887
        }
 
12888
        if (this.displayIndentGuides) {
 
12889
            this.$indentGuideRe =  /\s\S| \t|\t |\s$/;
 
12890
            var className = "ace_indent-guide";
 
12891
            if (this.showInvisibles) {
 
12892
                className += " ace_invisible";
 
12893
                var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize);
 
12894
                var tabContent = this.TAB_CHAR + lang.stringRepeat("\xa0", this.tabSize - 1);
 
12895
            } else{
 
12896
                var spaceContent = lang.stringRepeat("\xa0", this.tabSize);
 
12897
                var tabContent = spaceContent;
 
12898
            }
 
12899
 
 
12900
            this.$tabStrings[" "] = "<span class='" + className + "'>" + spaceContent + "</span>";
 
12901
            this.$tabStrings["\t"] = "<span class='" + className + "'>" + tabContent + "</span>";
 
12902
        }
 
12903
    };
 
12904
 
 
12905
    this.updateLines = function(config, firstRow, lastRow) {
 
12906
        if (this.config.lastRow != config.lastRow ||
 
12907
            this.config.firstRow != config.firstRow) {
 
12908
            this.scrollLines(config);
 
12909
        }
 
12910
        this.config = config;
 
12911
 
 
12912
        var first = Math.max(firstRow, config.firstRow);
 
12913
        var last = Math.min(lastRow, config.lastRow);
 
12914
 
 
12915
        var lineElements = this.element.childNodes;
 
12916
        var lineElementsIdx = 0;
 
12917
 
 
12918
        for (var row = config.firstRow; row < first; row++) {
 
12919
            var foldLine = this.session.getFoldLine(row);
 
12920
            if (foldLine) {
 
12921
                if (foldLine.containsRow(first)) {
 
12922
                    first = foldLine.start.row;
 
12923
                    break;
 
12924
                } else {
 
12925
                    row = foldLine.end.row;
 
12926
                }
 
12927
            }
 
12928
            lineElementsIdx ++;
 
12929
        }
 
12930
 
 
12931
        var row = first;
 
12932
        var foldLine = this.session.getNextFoldLine(row);
 
12933
        var foldStart = foldLine ? foldLine.start.row : Infinity;
 
12934
 
 
12935
        while (true) {
 
12936
            if (row > foldStart) {
 
12937
                row = foldLine.end.row+1;
 
12938
                foldLine = this.session.getNextFoldLine(row, foldLine);
 
12939
                foldStart = foldLine ? foldLine.start.row :Infinity;
 
12940
            }
 
12941
            if (row > last)
 
12942
                break;
 
12943
 
 
12944
            var lineElement = lineElements[lineElementsIdx++];
 
12945
            if (lineElement) {
 
12946
                var html = [];
 
12947
                this.$renderLine(
 
12948
                    html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
 
12949
                );
 
12950
                dom.setInnerHtml(lineElement, html.join(""));
 
12951
            }
 
12952
            row++;
 
12953
        }
 
12954
    };
 
12955
 
 
12956
    this.scrollLines = function(config) {
 
12957
        var oldConfig = this.config;
 
12958
        this.config = config;
 
12959
 
 
12960
        if (!oldConfig || oldConfig.lastRow < config.firstRow)
 
12961
            return this.update(config);
 
12962
 
 
12963
        if (config.lastRow < oldConfig.firstRow)
 
12964
            return this.update(config);
 
12965
 
 
12966
        var el = this.element;
 
12967
        if (oldConfig.firstRow < config.firstRow)
 
12968
            for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
 
12969
                el.removeChild(el.firstChild);
 
12970
 
 
12971
        if (oldConfig.lastRow > config.lastRow)
 
12972
            for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
 
12973
                el.removeChild(el.lastChild);
 
12974
 
 
12975
        if (config.firstRow < oldConfig.firstRow) {
 
12976
            var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);
 
12977
            if (el.firstChild)
 
12978
                el.insertBefore(fragment, el.firstChild);
 
12979
            else
 
12980
                el.appendChild(fragment);
 
12981
        }
 
12982
 
 
12983
        if (config.lastRow > oldConfig.lastRow) {
 
12984
            var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow);
 
12985
            el.appendChild(fragment);
 
12986
        }
 
12987
    };
 
12988
 
 
12989
    this.$renderLinesFragment = function(config, firstRow, lastRow) {
 
12990
        var fragment = this.element.ownerDocument.createDocumentFragment();
 
12991
        var row = firstRow;
 
12992
        var foldLine = this.session.getNextFoldLine(row);
 
12993
        var foldStart = foldLine ? foldLine.start.row : Infinity;
 
12994
 
 
12995
        while (true) {
 
12996
            if (row > foldStart) {
 
12997
                row = foldLine.end.row+1;
 
12998
                foldLine = this.session.getNextFoldLine(row, foldLine);
 
12999
                foldStart = foldLine ? foldLine.start.row : Infinity;
 
13000
            }
 
13001
            if (row > lastRow)
 
13002
                break;
 
13003
 
 
13004
            var container = dom.createElement("div");
 
13005
 
 
13006
            var html = [];
 
13007
            this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
 
13008
            container.innerHTML = html.join("");
 
13009
            if (this.$useLineGroups()) {
 
13010
                container.className = 'ace_line_group';
 
13011
                fragment.appendChild(container);
 
13012
            } else {
 
13013
                var lines = container.childNodes
 
13014
                while(lines.length)
 
13015
                    fragment.appendChild(lines[0]);
 
13016
            }
 
13017
 
 
13018
            row++;
 
13019
        }
 
13020
        return fragment;
 
13021
    };
 
13022
 
 
13023
    this.update = function(config) {
 
13024
        this.config = config;
 
13025
 
 
13026
        var html = [];
 
13027
        var firstRow = config.firstRow, lastRow = config.lastRow;
 
13028
 
 
13029
        var row = firstRow;
 
13030
        var foldLine = this.session.getNextFoldLine(row);
 
13031
        var foldStart = foldLine ? foldLine.start.row : Infinity;
 
13032
 
 
13033
        while (true) {
 
13034
            if (row > foldStart) {
 
13035
                row = foldLine.end.row+1;
 
13036
                foldLine = this.session.getNextFoldLine(row, foldLine);
 
13037
                foldStart = foldLine ? foldLine.start.row :Infinity;
 
13038
            }
 
13039
            if (row > lastRow)
 
13040
                break;
 
13041
 
 
13042
            if (this.$useLineGroups())
 
13043
                html.push("<div class='ace_line_group'>")
 
13044
 
 
13045
            this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
 
13046
 
 
13047
            if (this.$useLineGroups())
 
13048
                html.push("</div>"); // end the line group
 
13049
 
 
13050
            row++;
 
13051
        }
 
13052
        this.element = dom.setInnerHtml(this.element, html.join(""));
 
13053
    };
 
13054
 
 
13055
    this.$textToken = {
 
13056
        "text": true,
 
13057
        "rparen": true,
 
13058
        "lparen": true
 
13059
    };
 
13060
 
 
13061
    this.$renderToken = function(stringBuilder, screenColumn, token, value) {
 
13062
        var self = this;
 
13063
        var replaceReg = /\t|&|<|( +)|([\x00-\x1f\x80-\xa0\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\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]/g;
 
13064
        var replaceFunc = function(c, a, b, tabIdx, idx4) {
 
13065
            if (a) {
 
13066
                return self.showInvisibles ?
 
13067
                    "<span class='ace_invisible'>" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "</span>" :
 
13068
                    lang.stringRepeat("\xa0", c.length);
 
13069
            } else if (c == "&") {
 
13070
                return "&#38;";
 
13071
            } else if (c == "<") {
 
13072
                return "&#60;";
 
13073
            } else if (c == "\t") {
 
13074
                var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);
 
13075
                screenColumn += tabSize - 1;
 
13076
                return self.$tabStrings[tabSize];
 
13077
            } else if (c == "\u3000") {
 
13078
                var classToUse = self.showInvisibles ? "ace_cjk ace_invisible" : "ace_cjk";
 
13079
                var space = self.showInvisibles ? self.SPACE_CHAR : "";
 
13080
                screenColumn += 1;
 
13081
                return "<span class='" + classToUse + "' style='width:" +
 
13082
                    (self.config.characterWidth * 2) +
 
13083
                    "px'>" + space + "</span>";
 
13084
            } else if (b) {
 
13085
                return "<span class='ace_invisible ace_invalid'>" + self.SPACE_CHAR + "</span>";
 
13086
            } else {
 
13087
                screenColumn += 1;
 
13088
                return "<span class='ace_cjk' style='width:" +
 
13089
                    (self.config.characterWidth * 2) +
 
13090
                    "px'>" + c + "</span>";
 
13091
            }
 
13092
        };
 
13093
 
 
13094
        var output = value.replace(replaceReg, replaceFunc);
 
13095
 
 
13096
        if (!this.$textToken[token.type]) {
 
13097
            var classes = "ace_" + token.type.replace(/\./g, " ace_");
 
13098
            var style = "";
 
13099
            if (token.type == "fold")
 
13100
                style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' ";
 
13101
            stringBuilder.push("<span class='", classes, "'", style, ">", output, "</span>");
 
13102
        }
 
13103
        else {
 
13104
            stringBuilder.push(output);
 
13105
        }
 
13106
        return screenColumn + value.length;
 
13107
    };
 
13108
 
 
13109
    this.renderIndentGuide = function(stringBuilder, value) {
 
13110
        var cols = value.search(this.$indentGuideRe);
 
13111
        if (cols <= 0)
 
13112
            return value;
 
13113
        if (value[0] == " ") {
 
13114
            cols -= cols % this.tabSize;
 
13115
            stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize));
 
13116
            return value.substr(cols);
 
13117
        } else if (value[0] == "\t") {
 
13118
            stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols));
 
13119
            return value.substr(cols);
 
13120
        }
 
13121
        return value;
 
13122
    };
 
13123
 
 
13124
    this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) {
 
13125
        var chars = 0;
 
13126
        var split = 0;
 
13127
        var splitChars = splits[0];
 
13128
        var screenColumn = 0;
 
13129
 
 
13130
        for (var i = 0; i < tokens.length; i++) {
 
13131
            var token = tokens[i];
 
13132
            var value = token.value;
 
13133
            if (i == 0 && this.displayIndentGuides) {
 
13134
                chars = value.length;
 
13135
                value = this.renderIndentGuide(stringBuilder, value);
 
13136
                if (!value)
 
13137
                    continue;
 
13138
                chars -= value.length;
 
13139
            }
 
13140
 
 
13141
            if (chars + value.length < splitChars) {
 
13142
                screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
 
13143
                chars += value.length;
 
13144
            } else {
 
13145
                while (chars + value.length >= splitChars) {
 
13146
                    screenColumn = this.$renderToken(
 
13147
                        stringBuilder, screenColumn,
 
13148
                        token, value.substring(0, splitChars - chars)
 
13149
                    );
 
13150
                    value = value.substring(splitChars - chars);
 
13151
                    chars = splitChars;
 
13152
 
 
13153
                    if (!onlyContents) {
 
13154
                        stringBuilder.push("</div>",
 
13155
                            "<div class='ace_line' style='height:",
 
13156
                            this.config.lineHeight, "px'>"
 
13157
                        );
 
13158
                    }
 
13159
 
 
13160
                    split ++;
 
13161
                    screenColumn = 0;
 
13162
                    splitChars = splits[split] || Number.MAX_VALUE;
 
13163
                }
 
13164
                if (value.length != 0) {
 
13165
                    chars += value.length;
 
13166
                    screenColumn = this.$renderToken(
 
13167
                        stringBuilder, screenColumn, token, value
 
13168
                    );
 
13169
                }
 
13170
            }
 
13171
        }
 
13172
    };
 
13173
 
 
13174
    this.$renderSimpleLine = function(stringBuilder, tokens) {
 
13175
        var screenColumn = 0;
 
13176
        var token = tokens[0];
 
13177
        var value = token.value;
 
13178
        if (this.displayIndentGuides)
 
13179
            value = this.renderIndentGuide(stringBuilder, value);
 
13180
        if (value)
 
13181
            screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
 
13182
        for (var i = 1; i < tokens.length; i++) {
 
13183
            token = tokens[i];
 
13184
            value = token.value;
 
13185
            screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
 
13186
        }
 
13187
    };
 
13188
    this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) {
 
13189
        if (!foldLine && foldLine != false)
 
13190
            foldLine = this.session.getFoldLine(row);
 
13191
 
 
13192
        if (foldLine)
 
13193
            var tokens = this.$getFoldLineTokens(row, foldLine);
 
13194
        else
 
13195
            var tokens = this.session.getTokens(row);
 
13196
 
 
13197
 
 
13198
        if (!onlyContents) {
 
13199
            stringBuilder.push(
 
13200
                "<div class='ace_line' style='height:", this.config.lineHeight, "px'>"
 
13201
            );
 
13202
        }
 
13203
 
 
13204
        if (tokens.length) {
 
13205
            var splits = this.session.getRowSplitData(row);
 
13206
            if (splits && splits.length)
 
13207
                this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);
 
13208
            else
 
13209
                this.$renderSimpleLine(stringBuilder, tokens);
 
13210
        }
 
13211
 
 
13212
        if (this.showInvisibles) {
 
13213
            if (foldLine)
 
13214
                row = foldLine.end.row
 
13215
 
 
13216
            stringBuilder.push(
 
13217
                "<span class='ace_invisible'>",
 
13218
                row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
 
13219
                "</span>"
 
13220
            );
 
13221
        }
 
13222
        if (!onlyContents)
 
13223
            stringBuilder.push("</div>");
 
13224
    };
 
13225
 
 
13226
    this.$getFoldLineTokens = function(row, foldLine) {
 
13227
        var session = this.session;
 
13228
        var renderTokens = [];
 
13229
 
 
13230
        function addTokens(tokens, from, to) {
 
13231
            var idx = 0, col = 0;
 
13232
            while ((col + tokens[idx].value.length) < from) {
 
13233
                col += tokens[idx].value.length;
 
13234
                idx++;
 
13235
 
 
13236
                if (idx == tokens.length)
 
13237
                    return;
 
13238
            }
 
13239
            if (col != from) {
 
13240
                var value = tokens[idx].value.substring(from - col);
 
13241
                if (value.length > (to - from))
 
13242
                    value = value.substring(0, to - from);
 
13243
 
 
13244
                renderTokens.push({
 
13245
                    type: tokens[idx].type,
 
13246
                    value: value
 
13247
                });
 
13248
 
 
13249
                col = from + value.length;
 
13250
                idx += 1;
 
13251
            }
 
13252
 
 
13253
            while (col < to && idx < tokens.length) {
 
13254
                var value = tokens[idx].value;
 
13255
                if (value.length + col > to) {
 
13256
                    renderTokens.push({
 
13257
                        type: tokens[idx].type,
 
13258
                        value: value.substring(0, to - col)
 
13259
                    });
 
13260
                } else
 
13261
                    renderTokens.push(tokens[idx]);
 
13262
                col += value.length;
 
13263
                idx += 1;
 
13264
            }
 
13265
        }
 
13266
 
 
13267
        var tokens = session.getTokens(row);
 
13268
        foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
 
13269
            if (placeholder != null) {
 
13270
                renderTokens.push({
 
13271
                    type: "fold",
 
13272
                    value: placeholder
 
13273
                });
 
13274
            } else {
 
13275
                if (isNewRow)
 
13276
                    tokens = session.getTokens(row);
 
13277
 
 
13278
                if (tokens.length)
 
13279
                    addTokens(tokens, lastColumn, column);
 
13280
            }
 
13281
        }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
 
13282
 
 
13283
        return renderTokens;
 
13284
    };
 
13285
 
 
13286
    this.$useLineGroups = function() {
 
13287
        return this.session.getUseWrapMode();
 
13288
    };
 
13289
 
 
13290
    this.destroy = function() {
 
13291
        clearInterval(this.$pollSizeChangesTimer);
 
13292
        if (this.$measureNode)
 
13293
            this.$measureNode.parentNode.removeChild(this.$measureNode);
 
13294
        delete this.$measureNode;
 
13295
    };
 
13296
 
 
13297
}).call(Text.prototype);
 
13298
 
 
13299
exports.Text = Text;
 
13300
 
 
13301
});
 
13302
 
 
13303
define('ace/layer/cursor', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
 
13304
 
 
13305
 
 
13306
var dom = require("../lib/dom");
 
13307
 
 
13308
var Cursor = function(parentEl) {
 
13309
    this.element = dom.createElement("div");
 
13310
    this.element.className = "ace_layer ace_cursor-layer";
 
13311
    parentEl.appendChild(this.element);
 
13312
 
 
13313
    this.isVisible = false;
 
13314
    this.isBlinking = true;
 
13315
    this.blinkInterval = 1000;
 
13316
    this.smoothBlinking = false;
 
13317
 
 
13318
    this.cursors = [];
 
13319
    this.cursor = this.addCursor();
 
13320
    dom.addCssClass(this.element, "ace_hidden-cursors");
 
13321
};
 
13322
 
 
13323
(function() {
 
13324
 
 
13325
    this.$padding = 0;
 
13326
    this.setPadding = function(padding) {
 
13327
        this.$padding = padding;
 
13328
    };
 
13329
 
 
13330
    this.setSession = function(session) {
 
13331
        this.session = session;
 
13332
    };
 
13333
 
 
13334
    this.setBlinking = function(blinking) {
 
13335
        if (blinking != this.isBlinking){
 
13336
            this.isBlinking = blinking;
 
13337
            this.restartTimer();
 
13338
        }
 
13339
    };
 
13340
 
 
13341
    this.setBlinkInterval = function(blinkInterval) {
 
13342
        if (blinkInterval != this.blinkInterval){
 
13343
            this.blinkInterval = blinkInterval;
 
13344
            this.restartTimer();
 
13345
        }
 
13346
    };
 
13347
 
 
13348
    this.setSmoothBlinking = function(smoothBlinking) {
 
13349
        if (smoothBlinking != this.smoothBlinking) {
 
13350
            this.smoothBlinking = smoothBlinking;
 
13351
            if (smoothBlinking)
 
13352
                dom.addCssClass(this.element, "ace_smooth-blinking");
 
13353
            else
 
13354
                dom.removeCssClass(this.element, "ace_smooth-blinking");
 
13355
            this.restartTimer();
 
13356
        }
 
13357
    };
 
13358
 
 
13359
    this.addCursor = function() {
 
13360
        var el = dom.createElement("div");
 
13361
        el.className = "ace_cursor";
 
13362
        this.element.appendChild(el);
 
13363
        this.cursors.push(el);
 
13364
        return el;
 
13365
    };
 
13366
 
 
13367
    this.removeCursor = function() {
 
13368
        if (this.cursors.length > 1) {
 
13369
            var el = this.cursors.pop();
 
13370
            el.parentNode.removeChild(el);
 
13371
            return el;
 
13372
        }
 
13373
    };
 
13374
 
 
13375
    this.hideCursor = function() {
 
13376
        this.isVisible = false;
 
13377
        dom.addCssClass(this.element, "ace_hidden-cursors");
 
13378
        this.restartTimer();
 
13379
    };
 
13380
 
 
13381
    this.showCursor = function() {
 
13382
        this.isVisible = true;
 
13383
        dom.removeCssClass(this.element, "ace_hidden-cursors");
 
13384
        this.restartTimer();
 
13385
    };
 
13386
 
 
13387
    this.restartTimer = function() {
 
13388
        clearInterval(this.intervalId);
 
13389
        clearTimeout(this.timeoutId);
 
13390
        if (this.smoothBlinking)
 
13391
            dom.removeCssClass(this.element, "ace_smooth-blinking");
 
13392
        for (var i = this.cursors.length; i--; )
 
13393
            this.cursors[i].style.opacity = "";
 
13394
 
 
13395
        if (!this.isBlinking || !this.blinkInterval || !this.isVisible)
 
13396
            return;
 
13397
 
 
13398
        if (this.smoothBlinking)
 
13399
            setTimeout(function(){
 
13400
                dom.addCssClass(this.element, "ace_smooth-blinking");
 
13401
            }.bind(this));
 
13402
 
 
13403
        var blink = function(){
 
13404
            this.timeoutId = setTimeout(function() {
 
13405
                for (var i = this.cursors.length; i--; ) {
 
13406
                    this.cursors[i].style.opacity = 0;
 
13407
                }
 
13408
            }.bind(this), 0.6 * this.blinkInterval);
 
13409
        }.bind(this);
 
13410
 
 
13411
        this.intervalId = setInterval(function() {
 
13412
            for (var i = this.cursors.length; i--; ) {
 
13413
                this.cursors[i].style.opacity = "";
 
13414
            }
 
13415
            blink();
 
13416
        }.bind(this), this.blinkInterval);
 
13417
 
 
13418
        blink();
 
13419
    };
 
13420
 
 
13421
    this.getPixelPosition = function(position, onScreen) {
 
13422
        if (!this.config || !this.session)
 
13423
            return {left : 0, top : 0};
 
13424
 
 
13425
        if (!position)
 
13426
            position = this.session.selection.getCursor();
 
13427
        var pos = this.session.documentToScreenPosition(position);
 
13428
        var cursorLeft = this.$padding + pos.column * this.config.characterWidth;
 
13429
        var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *
 
13430
            this.config.lineHeight;
 
13431
 
 
13432
        return {left : cursorLeft, top : cursorTop};
 
13433
    };
 
13434
 
 
13435
    this.update = function(config) {
 
13436
        this.config = config;
 
13437
 
 
13438
        var selections = this.session.$selectionMarkers;
 
13439
        var i = 0, cursorIndex = 0;
 
13440
 
 
13441
        if (selections === undefined || selections.length === 0){
 
13442
            selections = [{cursor: null}];
 
13443
        }
 
13444
 
 
13445
        for (var i = 0, n = selections.length; i < n; i++) {
 
13446
            var pixelPos = this.getPixelPosition(selections[i].cursor, true);
 
13447
            if ((pixelPos.top > config.height + config.offset ||
 
13448
                 pixelPos.top < -config.offset) && i > 1) {
 
13449
                continue;
 
13450
            }
 
13451
 
 
13452
            var style = (this.cursors[cursorIndex++] || this.addCursor()).style;
 
13453
 
 
13454
            style.left = pixelPos.left + "px";
 
13455
            style.top = pixelPos.top + "px";
 
13456
            style.width = config.characterWidth + "px";
 
13457
            style.height = config.lineHeight + "px";
 
13458
        }
 
13459
        while (this.cursors.length > cursorIndex)
 
13460
            this.removeCursor();
 
13461
 
 
13462
        var overwrite = this.session.getOverwrite();
 
13463
        this.$setOverwrite(overwrite);
 
13464
        this.$pixelPos = pixelPos;
 
13465
        this.restartTimer();
 
13466
    };
 
13467
 
 
13468
    this.$setOverwrite = function(overwrite) {
 
13469
        if (overwrite != this.overwrite) {
 
13470
            this.overwrite = overwrite;
 
13471
            if (overwrite)
 
13472
                dom.addCssClass(this.element, "ace_overwrite-cursors");
 
13473
            else
 
13474
                dom.removeCssClass(this.element, "ace_overwrite-cursors");
 
13475
        }
 
13476
    };
 
13477
 
 
13478
    this.destroy = function() {
 
13479
        clearInterval(this.intervalId);
 
13480
        clearTimeout(this.timeoutId);
 
13481
    };
 
13482
 
 
13483
}).call(Cursor.prototype);
 
13484
 
 
13485
exports.Cursor = Cursor;
 
13486
 
 
13487
});
 
13488
 
 
13489
define('ace/scrollbar', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/event_emitter'], function(require, exports, module) {
 
13490
 
 
13491
 
 
13492
var oop = require("./lib/oop");
 
13493
var dom = require("./lib/dom");
 
13494
var event = require("./lib/event");
 
13495
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
13496
var ScrollBar = function(parent) {
 
13497
    this.element = dom.createElement("div");
 
13498
    this.element.className = "ace_scrollbar";
 
13499
 
 
13500
    this.inner = dom.createElement("div");
 
13501
    this.inner.className = "ace_scrollbar-inner";
 
13502
    this.element.appendChild(this.inner);
 
13503
 
 
13504
    parent.appendChild(this.element);
 
13505
    this.width = dom.scrollbarWidth(parent.ownerDocument);
 
13506
    this.element.style.width = (this.width || 15) + 5 + "px";
 
13507
 
 
13508
    event.addListener(this.element, "scroll", this.onScroll.bind(this));
 
13509
};
 
13510
 
 
13511
(function() {
 
13512
    oop.implement(this, EventEmitter);
 
13513
    this.onScroll = function() {
 
13514
        if (!this.skipEvent) {
 
13515
            this.scrollTop = this.element.scrollTop;
 
13516
            this._emit("scroll", {data: this.scrollTop});
 
13517
        }
 
13518
        this.skipEvent = false;
 
13519
    };
 
13520
    this.getWidth = function() {
 
13521
        return this.width;
 
13522
    };
 
13523
    this.setHeight = function(height) {
 
13524
        this.element.style.height = height + "px";
 
13525
    };
 
13526
    this.setInnerHeight = function(height) {
 
13527
        this.inner.style.height = height + "px";
 
13528
    };
 
13529
    this.setScrollTop = function(scrollTop) {
 
13530
        if (this.scrollTop != scrollTop) {
 
13531
            this.skipEvent = true;
 
13532
            this.scrollTop = this.element.scrollTop = scrollTop;
 
13533
        }
 
13534
    };
 
13535
 
 
13536
}).call(ScrollBar.prototype);
 
13537
 
 
13538
exports.ScrollBar = ScrollBar;
 
13539
});
 
13540
 
 
13541
define('ace/renderloop', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
 
13542
 
 
13543
 
 
13544
var event = require("./lib/event");
 
13545
 
 
13546
 
 
13547
var RenderLoop = function(onRender, win) {
 
13548
    this.onRender = onRender;
 
13549
    this.pending = false;
 
13550
    this.changes = 0;
 
13551
    this.window = win || window;
 
13552
};
 
13553
 
 
13554
(function() {
 
13555
 
 
13556
 
 
13557
    this.schedule = function(change) {
 
13558
        this.changes = this.changes | change;
 
13559
        if (!this.pending) {
 
13560
            this.pending = true;
 
13561
            var _self = this;
 
13562
            event.nextFrame(function() {
 
13563
                _self.pending = false;
 
13564
                var changes;
 
13565
                while (changes = _self.changes) {
 
13566
                    _self.changes = 0;
 
13567
                    _self.onRender(changes);
 
13568
                }
 
13569
            }, this.window);
 
13570
        }
 
13571
    };
 
13572
 
 
13573
}).call(RenderLoop.prototype);
 
13574
 
 
13575
exports.RenderLoop = RenderLoop;
 
13576
});
 
13577
 
 
13578
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'], function(require, exports, module) {
 
13579
 
 
13580
var RangeList = require("./range_list").RangeList;
 
13581
var Range = require("./range").Range;
 
13582
var Selection = require("./selection").Selection;
 
13583
var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
 
13584
var event = require("./lib/event");
 
13585
var lang = require("./lib/lang");
 
13586
var commands = require("./commands/multi_select_commands");
 
13587
exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
 
13588
var Search = require("./search").Search;
 
13589
var search = new Search();
 
13590
 
 
13591
function find(session, needle, dir) {
 
13592
    search.$options.wrap = true;
 
13593
    search.$options.needle = needle;
 
13594
    search.$options.backwards = dir == -1;
 
13595
    return search.find(session);
 
13596
}
 
13597
var EditSession = require("./edit_session").EditSession;
 
13598
(function() {
 
13599
    this.getSelectionMarkers = function() {
 
13600
        return this.$selectionMarkers;
 
13601
    };
 
13602
}).call(EditSession.prototype);
 
13603
(function() {
 
13604
    this.ranges = null;
 
13605
    this.rangeList = null;
 
13606
    this.addRange = function(range, $blockChangeEvents) {
 
13607
        if (!range)
 
13608
            return;
 
13609
 
 
13610
        if (!this.inMultiSelectMode && this.rangeCount == 0) {
 
13611
            var oldRange = this.toOrientedRange();
 
13612
            this.rangeList.add(oldRange);
 
13613
            this.rangeList.add(range);
 
13614
            if (this.rangeList.ranges.length != 2) {
 
13615
                this.rangeList.removeAll();
 
13616
                return $blockChangeEvents || this.fromOrientedRange(range);
 
13617
            }
 
13618
            this.rangeList.removeAll();
 
13619
            this.rangeList.add(oldRange);
 
13620
            this.$onAddRange(oldRange);
 
13621
        }
 
13622
 
 
13623
        if (!range.cursor)
 
13624
            range.cursor = range.end;
 
13625
 
 
13626
        var removed = this.rangeList.add(range);
 
13627
 
 
13628
        this.$onAddRange(range);
 
13629
 
 
13630
        if (removed.length)
 
13631
            this.$onRemoveRange(removed);
 
13632
 
 
13633
        if (this.rangeCount > 1 && !this.inMultiSelectMode) {
 
13634
            this._emit("multiSelect");
 
13635
            this.inMultiSelectMode = true;
 
13636
            this.session.$undoSelect = false;
 
13637
            this.rangeList.attach(this.session);
 
13638
        }
 
13639
 
 
13640
        return $blockChangeEvents || this.fromOrientedRange(range);
 
13641
    };
 
13642
 
 
13643
    this.toSingleRange = function(range) {
 
13644
        range = range || this.ranges[0];
 
13645
        var removed = this.rangeList.removeAll();
 
13646
        if (removed.length)
 
13647
            this.$onRemoveRange(removed);
 
13648
 
 
13649
        range && this.fromOrientedRange(range);
 
13650
    };
 
13651
    this.substractPoint = function(pos) {
 
13652
        var removed = this.rangeList.substractPoint(pos);
 
13653
        if (removed) {
 
13654
            this.$onRemoveRange(removed);
 
13655
            return removed[0];
 
13656
        }
 
13657
    };
 
13658
    this.mergeOverlappingRanges = function() {
 
13659
        var removed = this.rangeList.merge();
 
13660
        if (removed.length)
 
13661
            this.$onRemoveRange(removed);
 
13662
        else if(this.ranges[0])
 
13663
            this.fromOrientedRange(this.ranges[0]);
 
13664
    };
 
13665
 
 
13666
    this.$onAddRange = function(range) {
 
13667
        this.rangeCount = this.rangeList.ranges.length;
 
13668
        this.ranges.unshift(range);
 
13669
        this._emit("addRange", {range: range});
 
13670
    };
 
13671
 
 
13672
    this.$onRemoveRange = function(removed) {
 
13673
        this.rangeCount = this.rangeList.ranges.length;
 
13674
        if (this.rangeCount == 1 && this.inMultiSelectMode) {
 
13675
            var lastRange = this.rangeList.ranges.pop();
 
13676
            removed.push(lastRange);
 
13677
            this.rangeCount = 0;
 
13678
        }
 
13679
 
 
13680
        for (var i = removed.length; i--; ) {
 
13681
            var index = this.ranges.indexOf(removed[i]);
 
13682
            this.ranges.splice(index, 1);
 
13683
        }
 
13684
 
 
13685
        this._emit("removeRange", {ranges: removed});
 
13686
 
 
13687
        if (this.rangeCount == 0 && this.inMultiSelectMode) {
 
13688
            this.inMultiSelectMode = false;
 
13689
            this._emit("singleSelect");
 
13690
            this.session.$undoSelect = true;
 
13691
            this.rangeList.detach(this.session);
 
13692
        }
 
13693
 
 
13694
        lastRange = lastRange || this.ranges[0];
 
13695
        if (lastRange && !lastRange.isEqual(this.getRange()))
 
13696
            this.fromOrientedRange(lastRange);
 
13697
    };
 
13698
    this.$initRangeList = function() {
 
13699
        if (this.rangeList)
 
13700
            return;
 
13701
 
 
13702
        this.rangeList = new RangeList();
 
13703
        this.ranges = [];
 
13704
        this.rangeCount = 0;
 
13705
    };
 
13706
    this.getAllRanges = function() {
 
13707
        return this.rangeList.ranges.concat();
 
13708
    };
 
13709
 
 
13710
    this.splitIntoLines = function () {
 
13711
        if (this.rangeCount > 1) {
 
13712
            var ranges = this.rangeList.ranges;
 
13713
            var lastRange = ranges[ranges.length - 1];
 
13714
            var range = Range.fromPoints(ranges[0].start, lastRange.end);
 
13715
 
 
13716
            this.toSingleRange();
 
13717
            this.setSelectionRange(range, lastRange.cursor == lastRange.start);
 
13718
        } else {
 
13719
            var range = this.getRange();
 
13720
            var isBackwards = this.isBackwards();
 
13721
            var startRow = range.start.row;
 
13722
            var endRow = range.end.row;
 
13723
            if (startRow == endRow) {
 
13724
                if (isBackwards)
 
13725
                    var start = range.end, end = range.start;
 
13726
                else
 
13727
                    var start = range.start, end = range.end;
 
13728
                
 
13729
                this.addRange(Range.fromPoints(end, end));
 
13730
                this.addRange(Range.fromPoints(start, start));
 
13731
                return;
 
13732
            }
 
13733
 
 
13734
            var rectSel = [];
 
13735
            var r = this.getLineRange(startRow, true);
 
13736
            r.start.column = range.start.column;
 
13737
            rectSel.push(r);
 
13738
 
 
13739
            for (var i = startRow + 1; i < endRow; i++)
 
13740
                rectSel.push(this.getLineRange(i, true));
 
13741
 
 
13742
            r = this.getLineRange(endRow, true);
 
13743
            r.end.column = range.end.column;
 
13744
            rectSel.push(r);
 
13745
 
 
13746
            rectSel.forEach(this.addRange, this);
 
13747
        }
 
13748
    };
 
13749
    this.toggleBlockSelection = function () {
 
13750
        if (this.rangeCount > 1) {
 
13751
            var ranges = this.rangeList.ranges;
 
13752
            var lastRange = ranges[ranges.length - 1];
 
13753
            var range = Range.fromPoints(ranges[0].start, lastRange.end);
 
13754
 
 
13755
            this.toSingleRange();
 
13756
            this.setSelectionRange(range, lastRange.cursor == lastRange.start);
 
13757
        } else {
 
13758
            var cursor = this.session.documentToScreenPosition(this.selectionLead);
 
13759
            var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
 
13760
 
 
13761
            var rectSel = this.rectangularRangeBlock(cursor, anchor);
 
13762
            rectSel.forEach(this.addRange, this);
 
13763
        }
 
13764
    };
 
13765
    this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
 
13766
        var rectSel = [];
 
13767
 
 
13768
        var xBackwards = screenCursor.column < screenAnchor.column;
 
13769
        if (xBackwards) {
 
13770
            var startColumn = screenCursor.column;
 
13771
            var endColumn = screenAnchor.column;
 
13772
        } else {
 
13773
            var startColumn = screenAnchor.column;
 
13774
            var endColumn = screenCursor.column;
 
13775
        }
 
13776
 
 
13777
        var yBackwards = screenCursor.row < screenAnchor.row;
 
13778
        if (yBackwards) {
 
13779
            var startRow = screenCursor.row;
 
13780
            var endRow = screenAnchor.row;
 
13781
        } else {
 
13782
            var startRow = screenAnchor.row;
 
13783
            var endRow = screenCursor.row;
 
13784
        }
 
13785
 
 
13786
        if (startColumn < 0)
 
13787
            startColumn = 0;
 
13788
        if (startRow < 0)
 
13789
            startRow = 0;
 
13790
 
 
13791
        if (startRow == endRow)
 
13792
            includeEmptyLines = true;
 
13793
 
 
13794
        for (var row = startRow; row <= endRow; row++) {
 
13795
            var range = Range.fromPoints(
 
13796
                this.session.screenToDocumentPosition(row, startColumn),
 
13797
                this.session.screenToDocumentPosition(row, endColumn)
 
13798
            );
 
13799
            if (range.isEmpty()) {
 
13800
                if (docEnd && isSamePoint(range.end, docEnd))
 
13801
                    break;
 
13802
                var docEnd = range.end;
 
13803
            }
 
13804
            range.cursor = xBackwards ? range.start : range.end;
 
13805
            rectSel.push(range);
 
13806
        }
 
13807
 
 
13808
        if (yBackwards)
 
13809
            rectSel.reverse();
 
13810
 
 
13811
        if (!includeEmptyLines) {
 
13812
            var end = rectSel.length - 1;
 
13813
            while (rectSel[end].isEmpty() && end > 0)
 
13814
                end--;
 
13815
            if (end > 0) {
 
13816
                var start = 0;
 
13817
                while (rectSel[start].isEmpty())
 
13818
                    start++;
 
13819
            }
 
13820
            for (var i = end; i >= start; i--) {
 
13821
                if (rectSel[i].isEmpty())
 
13822
                    rectSel.splice(i, 1);
 
13823
            }
 
13824
        }
 
13825
 
 
13826
        return rectSel;
 
13827
    };
 
13828
}).call(Selection.prototype);
 
13829
var Editor = require("./editor").Editor;
 
13830
(function() {
 
13831
    this.updateSelectionMarkers = function() {
 
13832
        this.renderer.updateCursor();
 
13833
        this.renderer.updateBackMarkers();
 
13834
    };
 
13835
    this.addSelectionMarker = function(orientedRange) {
 
13836
        if (!orientedRange.cursor)
 
13837
            orientedRange.cursor = orientedRange.end;
 
13838
 
 
13839
        var style = this.getSelectionStyle();
 
13840
        orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
 
13841
 
 
13842
        this.session.$selectionMarkers.push(orientedRange);
 
13843
        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
 
13844
        return orientedRange;
 
13845
    };
 
13846
    this.removeSelectionMarker = function(range) {
 
13847
        if (!range.marker)
 
13848
            return;
 
13849
        this.session.removeMarker(range.marker);
 
13850
        var index = this.session.$selectionMarkers.indexOf(range);
 
13851
        if (index != -1)
 
13852
            this.session.$selectionMarkers.splice(index, 1);
 
13853
        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
 
13854
    };
 
13855
 
 
13856
    this.removeSelectionMarkers = function(ranges) {
 
13857
        var markerList = this.session.$selectionMarkers;
 
13858
        for (var i = ranges.length; i--; ) {
 
13859
            var range = ranges[i];
 
13860
            if (!range.marker)
 
13861
                continue;
 
13862
            this.session.removeMarker(range.marker);
 
13863
            var index = markerList.indexOf(range);
 
13864
            if (index != -1)
 
13865
                markerList.splice(index, 1);
 
13866
        }
 
13867
        this.session.selectionMarkerCount = markerList.length;
 
13868
    };
 
13869
 
 
13870
    this.$onAddRange = function(e) {
 
13871
        this.addSelectionMarker(e.range);
 
13872
        this.renderer.updateCursor();
 
13873
        this.renderer.updateBackMarkers();
 
13874
    };
 
13875
 
 
13876
    this.$onRemoveRange = function(e) {
 
13877
        this.removeSelectionMarkers(e.ranges);
 
13878
        this.renderer.updateCursor();
 
13879
        this.renderer.updateBackMarkers();
 
13880
    };
 
13881
 
 
13882
    this.$onMultiSelect = function(e) {
 
13883
        if (this.inMultiSelectMode)
 
13884
            return;
 
13885
        this.inMultiSelectMode = true;
 
13886
 
 
13887
        this.setStyle("ace_multiselect");
 
13888
        this.keyBinding.addKeyboardHandler(commands.keyboardHandler);
 
13889
        this.commands.on("exec", this.$onMultiSelectExec);
 
13890
 
 
13891
        this.renderer.updateCursor();
 
13892
        this.renderer.updateBackMarkers();
 
13893
    };
 
13894
 
 
13895
    this.$onSingleSelect = function(e) {
 
13896
        if (this.session.multiSelect.inVirtualMode)
 
13897
            return;
 
13898
        this.inMultiSelectMode = false;
 
13899
 
 
13900
        this.unsetStyle("ace_multiselect");
 
13901
        this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);
 
13902
 
 
13903
        this.commands.removeEventListener("exec", this.$onMultiSelectExec);
 
13904
        this.renderer.updateCursor();
 
13905
        this.renderer.updateBackMarkers();
 
13906
    };
 
13907
 
 
13908
    this.$onMultiSelectExec = function(e) {
 
13909
        var command = e.command;
 
13910
        var editor = e.editor;
 
13911
        if (!editor.multiSelect)
 
13912
            return;
 
13913
        if (!command.multiSelectAction) {
 
13914
            command.exec(editor, e.args || {});
 
13915
            editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());
 
13916
            editor.multiSelect.mergeOverlappingRanges();
 
13917
        } else if (command.multiSelectAction == "forEach") {
 
13918
            editor.forEachSelection(command, e.args);
 
13919
        } else if (command.multiSelectAction == "forEachLine") {
 
13920
            editor.forEachSelection(command, e.args, true);
 
13921
        } else if (command.multiSelectAction == "single") {
 
13922
            editor.exitMultiSelectMode();
 
13923
            command.exec(editor, e.args || {});
 
13924
        } else {
 
13925
            command.multiSelectAction(editor, e.args || {});
 
13926
        }
 
13927
        e.preventDefault();
 
13928
    }; 
 
13929
    this.forEachSelection = function(cmd, args, $byLines) {
 
13930
        if (this.inVirtualSelectionMode)
 
13931
            return;
 
13932
 
 
13933
        var session = this.session;
 
13934
        var selection = this.selection;
 
13935
        var rangeList = selection.rangeList;
 
13936
 
 
13937
        var reg = selection._eventRegistry;
 
13938
        selection._eventRegistry = {};
 
13939
 
 
13940
        var tmpSel = new Selection(session);
 
13941
        this.inVirtualSelectionMode = true;
 
13942
        for (var i = rangeList.ranges.length; i--;) {
 
13943
            if ($byLines) {
 
13944
                while (i > 0 && rangeList.ranges[i].start.row == rangeList.ranges[i - 1].end.row)
 
13945
                    i--;
 
13946
            }
 
13947
            tmpSel.fromOrientedRange(rangeList.ranges[i]);
 
13948
            this.selection = session.selection = tmpSel;
 
13949
            cmd.exec(this, args || {});
 
13950
            tmpSel.toOrientedRange(rangeList.ranges[i]);
 
13951
        }
 
13952
        tmpSel.detach();
 
13953
 
 
13954
        this.selection = session.selection = selection;
 
13955
        this.inVirtualSelectionMode = false;
 
13956
        selection._eventRegistry = reg;
 
13957
        selection.mergeOverlappingRanges();
 
13958
 
 
13959
        this.onCursorChange();
 
13960
        this.onSelectionChange();
 
13961
    };
 
13962
    this.exitMultiSelectMode = function() {
 
13963
        if (this.inVirtualSelectionMode)
 
13964
            return;
 
13965
        this.multiSelect.toSingleRange();
 
13966
    };
 
13967
 
 
13968
    this.getCopyText = function() {
 
13969
        var text = "";
 
13970
        if (this.inMultiSelectMode) {
 
13971
            var ranges = this.multiSelect.rangeList.ranges;
 
13972
            text = [];
 
13973
            for (var i = 0; i < ranges.length; i++) {
 
13974
                text.push(this.session.getTextRange(ranges[i]));
 
13975
            }
 
13976
            text = text.join(this.session.getDocument().getNewLineCharacter());
 
13977
        } else if (!this.selection.isEmpty()) {
 
13978
            text = this.session.getTextRange(this.getSelectionRange());
 
13979
        }
 
13980
 
 
13981
        return text;
 
13982
    };
 
13983
    this.onPaste = function(text) {
 
13984
        if (this.$readOnly)
 
13985
            return;
 
13986
 
 
13987
        this._signal("paste", text);
 
13988
        if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
 
13989
            return this.insert(text);
 
13990
 
 
13991
        var lines = text.split(/\r\n|\r|\n/);
 
13992
        var ranges = this.selection.rangeList.ranges;
 
13993
 
 
13994
        if (lines.length > ranges.length || (lines.length <= 2 || !lines[1]))
 
13995
            return this.commands.exec("insertstring", this, text);
 
13996
 
 
13997
        for (var i = ranges.length; i--; ) {
 
13998
            var range = ranges[i];
 
13999
            if (!range.isEmpty())
 
14000
                this.session.remove(range);
 
14001
 
 
14002
            this.session.insert(range.start, lines[i]);
 
14003
        }
 
14004
    };
 
14005
    this.findAll = function(needle, options, additive) {
 
14006
        options = options || {};
 
14007
        options.needle = needle || options.needle;
 
14008
        this.$search.set(options);
 
14009
 
 
14010
        var ranges = this.$search.findAll(this.session);
 
14011
        if (!ranges.length)
 
14012
            return 0;
 
14013
 
 
14014
        this.$blockScrolling += 1;
 
14015
        var selection = this.multiSelect;
 
14016
 
 
14017
        if (!additive)
 
14018
            selection.toSingleRange(ranges[0]);
 
14019
 
 
14020
        for (var i = ranges.length; i--; )
 
14021
            selection.addRange(ranges[i], true);
 
14022
 
 
14023
        this.$blockScrolling -= 1;
 
14024
 
 
14025
        return ranges.length;
 
14026
    };
 
14027
    this.selectMoreLines = function(dir, skip) {
 
14028
        var range = this.selection.toOrientedRange();
 
14029
        var isBackwards = range.cursor == range.end;
 
14030
 
 
14031
        var screenLead = this.session.documentToScreenPosition(range.cursor);
 
14032
        if (this.selection.$desiredColumn)
 
14033
            screenLead.column = this.selection.$desiredColumn;
 
14034
 
 
14035
        var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
 
14036
 
 
14037
        if (!range.isEmpty()) {
 
14038
            var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
 
14039
            var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
 
14040
        } else {
 
14041
            var anchor = lead;
 
14042
        }
 
14043
 
 
14044
        if (isBackwards) {
 
14045
            var newRange = Range.fromPoints(lead, anchor);
 
14046
            newRange.cursor = newRange.start;
 
14047
        } else {
 
14048
            var newRange = Range.fromPoints(anchor, lead);
 
14049
            newRange.cursor = newRange.end;
 
14050
        }
 
14051
 
 
14052
        newRange.desiredColumn = screenLead.column;
 
14053
        if (!this.selection.inMultiSelectMode) {
 
14054
            this.selection.addRange(range);
 
14055
        } else {
 
14056
            if (skip)
 
14057
                var toRemove = range.cursor;
 
14058
        }
 
14059
 
 
14060
        this.selection.addRange(newRange);
 
14061
        if (toRemove)
 
14062
            this.selection.substractPoint(toRemove);
 
14063
    };
 
14064
    this.transposeSelections = function(dir) {
 
14065
        var session = this.session;
 
14066
        var sel = session.multiSelect;
 
14067
        var all = sel.ranges;
 
14068
 
 
14069
        for (var i = all.length; i--; ) {
 
14070
            var range = all[i];
 
14071
            if (range.isEmpty()) {
 
14072
                var tmp = session.getWordRange(range.start.row, range.start.column);
 
14073
                range.start.row = tmp.start.row;
 
14074
                range.start.column = tmp.start.column;
 
14075
                range.end.row = tmp.end.row;
 
14076
                range.end.column = tmp.end.column;
 
14077
            }
 
14078
        }
 
14079
        sel.mergeOverlappingRanges();
 
14080
 
 
14081
        var words = [];
 
14082
        for (var i = all.length; i--; ) {
 
14083
            var range = all[i];
 
14084
            words.unshift(session.getTextRange(range));
 
14085
        }
 
14086
 
 
14087
        if (dir < 0)
 
14088
            words.unshift(words.pop());
 
14089
        else
 
14090
            words.push(words.shift());
 
14091
 
 
14092
        for (var i = all.length; i--; ) {
 
14093
            var range = all[i];
 
14094
            var tmp = range.clone();
 
14095
            session.replace(range, words[i]);
 
14096
            range.start.row = tmp.start.row;
 
14097
            range.start.column = tmp.start.column;
 
14098
        }
 
14099
    };
 
14100
    this.selectMore = function(dir, skip) {
 
14101
        var session = this.session;
 
14102
        var sel = session.multiSelect;
 
14103
 
 
14104
        var range = sel.toOrientedRange();
 
14105
        if (range.isEmpty()) {
 
14106
            var range = session.getWordRange(range.start.row, range.start.column);
 
14107
            range.cursor = range.end;
 
14108
            this.multiSelect.addRange(range);
 
14109
        }
 
14110
        var needle = session.getTextRange(range);
 
14111
 
 
14112
        var newRange = find(session, needle, dir);
 
14113
        if (newRange) {
 
14114
            newRange.cursor = dir == -1 ? newRange.start : newRange.end;
 
14115
            this.multiSelect.addRange(newRange);
 
14116
        }
 
14117
        if (skip)
 
14118
            this.multiSelect.substractPoint(range.cursor);
 
14119
    };
 
14120
    this.alignCursors = function() {
 
14121
        var session = this.session;
 
14122
        var sel = session.multiSelect;
 
14123
        var ranges = sel.ranges;
 
14124
 
 
14125
        if (!ranges.length) {
 
14126
            var range = this.selection.getRange();
 
14127
            var fr = range.start.row, lr = range.end.row;
 
14128
            var lines = this.session.doc.removeLines(fr, lr);
 
14129
            lines = this.$reAlignText(lines);
 
14130
            this.session.doc.insertLines(fr, lines);
 
14131
            range.start.column = 0;
 
14132
            range.end.column = lines[lines.length - 1].length;
 
14133
            this.selection.setRange(range);
 
14134
        } else {
 
14135
            var row = -1;
 
14136
            var sameRowRanges = ranges.filter(function(r) {
 
14137
                if (r.cursor.row == row)
 
14138
                    return true;
 
14139
                row = r.cursor.row;
 
14140
            });
 
14141
            sel.$onRemoveRange(sameRowRanges);
 
14142
 
 
14143
            var maxCol = 0;
 
14144
            var minSpace = Infinity;
 
14145
            var spaceOffsets = ranges.map(function(r) {
 
14146
                var p = r.cursor;
 
14147
                var line = session.getLine(p.row);
 
14148
                var spaceOffset = line.substr(p.column).search(/\S/g);
 
14149
                if (spaceOffset == -1)
 
14150
                    spaceOffset = 0;
 
14151
 
 
14152
                if (p.column > maxCol)
 
14153
                    maxCol = p.column;
 
14154
                if (spaceOffset < minSpace)
 
14155
                    minSpace = spaceOffset;
 
14156
                return spaceOffset;
 
14157
            });
 
14158
            ranges.forEach(function(r, i) {
 
14159
                var p = r.cursor;
 
14160
                var l = maxCol - p.column;
 
14161
                var d = spaceOffsets[i] - minSpace;
 
14162
                if (l > d)
 
14163
                    session.insert(p, lang.stringRepeat(" ", l - d));
 
14164
                else
 
14165
                    session.remove(new Range(p.row, p.column, p.row, p.column - l + d));
 
14166
 
 
14167
                r.start.column = r.end.column = maxCol;
 
14168
                r.start.row = r.end.row = p.row;
 
14169
                r.cursor = r.end;
 
14170
            });
 
14171
            sel.fromOrientedRange(ranges[0]);
 
14172
            this.renderer.updateCursor();
 
14173
            this.renderer.updateBackMarkers();
 
14174
        }
 
14175
    };
 
14176
 
 
14177
    this.$reAlignText = function(lines) {
 
14178
        var isLeftAligned = true, isRightAligned = true;
 
14179
        var startW, textW, endW;
 
14180
 
 
14181
        return lines.map(function(line) {
 
14182
            var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/);
 
14183
            if (!m)
 
14184
                return [line];
 
14185
 
 
14186
            if (startW == null) {
 
14187
                startW = m[1].length;
 
14188
                textW = m[2].length;
 
14189
                endW = m[3].length;
 
14190
                return m;
 
14191
            }
 
14192
 
 
14193
            if (startW + textW + endW != m[1].length + m[2].length + m[3].length)
 
14194
                isRightAligned = false;
 
14195
            if (startW != m[1].length)
 
14196
                isLeftAligned = false;
 
14197
 
 
14198
            if (startW > m[1].length)
 
14199
                startW = m[1].length;
 
14200
            if (textW < m[2].length)
 
14201
                textW = m[2].length;
 
14202
            if (endW > m[3].length)
 
14203
                endW = m[3].length;
 
14204
 
 
14205
            return m;
 
14206
        }).map(isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);
 
14207
 
 
14208
        function spaces(n) {
 
14209
            return lang.stringRepeat(" ", n);
 
14210
        }
 
14211
 
 
14212
        function alignLeft(m) {
 
14213
            return !m[2] ? m[0] : spaces(startW) + m[2]
 
14214
                + spaces(textW - m[2].length + endW)
 
14215
                + m[4].replace(/^([=:])\s+/, "$1 ")
 
14216
        }
 
14217
        function alignRight(m) {
 
14218
            return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]
 
14219
                + spaces(endW, " ")
 
14220
                + m[4].replace(/^([=:])\s+/, "$1 ")
 
14221
        }
 
14222
        function unAlign(m) {
 
14223
            return !m[2] ? m[0] : spaces(startW) + m[2]
 
14224
                + spaces(endW)
 
14225
                + m[4].replace(/^([=:])\s+/, "$1 ")
 
14226
        }
 
14227
    }
 
14228
}).call(Editor.prototype);
 
14229
 
 
14230
 
 
14231
function isSamePoint(p1, p2) {
 
14232
    return p1.row == p2.row && p1.column == p2.column;
 
14233
}
 
14234
exports.onSessionChange = function(e) {
 
14235
    var session = e.session;
 
14236
    if (!session.multiSelect) {
 
14237
        session.$selectionMarkers = [];
 
14238
        session.selection.$initRangeList();
 
14239
        session.multiSelect = session.selection;
 
14240
    }
 
14241
    this.multiSelect = session.multiSelect;
 
14242
 
 
14243
    var oldSession = e.oldSession;
 
14244
    if (oldSession) {
 
14245
        if (oldSession.multiSelect && oldSession.multiSelect.editor == this)
 
14246
            oldSession.multiSelect.editor = null;
 
14247
 
 
14248
        session.multiSelect.removeEventListener("addRange", this.$onAddRange);
 
14249
        session.multiSelect.removeEventListener("removeRange", this.$onRemoveRange);
 
14250
        session.multiSelect.removeEventListener("multiSelect", this.$onMultiSelect);
 
14251
        session.multiSelect.removeEventListener("singleSelect", this.$onSingleSelect);
 
14252
    }
 
14253
 
 
14254
    session.multiSelect.on("addRange", this.$onAddRange);
 
14255
    session.multiSelect.on("removeRange", this.$onRemoveRange);
 
14256
    session.multiSelect.on("multiSelect", this.$onMultiSelect);
 
14257
    session.multiSelect.on("singleSelect", this.$onSingleSelect);
 
14258
 
 
14259
    if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
 
14260
        if (session.selection.inMultiSelectMode)
 
14261
            this.$onMultiSelect();
 
14262
        else
 
14263
            this.$onSingleSelect();
 
14264
    }
 
14265
};
 
14266
function MultiSelect(editor) {
 
14267
    editor.$onAddRange = editor.$onAddRange.bind(editor);
 
14268
    editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
 
14269
    editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
 
14270
    editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
 
14271
 
 
14272
    exports.onSessionChange.call(editor, editor);
 
14273
    editor.on("changeSession", exports.onSessionChange.bind(editor));
 
14274
 
 
14275
    editor.on("mousedown", onMouseDown);
 
14276
    editor.commands.addCommands(commands.defaultCommands);
 
14277
 
 
14278
    addAltCursorListeners(editor);
 
14279
}
 
14280
 
 
14281
function addAltCursorListeners(editor){
 
14282
    var el = editor.textInput.getElement();
 
14283
    var altCursor = false;
 
14284
    var contentEl = editor.renderer.content;
 
14285
    event.addListener(el, "keydown", function(e) {
 
14286
        if (e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey)) {
 
14287
            if (!altCursor) {
 
14288
                contentEl.style.cursor = "crosshair";
 
14289
                altCursor = true;
 
14290
            }
 
14291
        } else if (altCursor) {
 
14292
            contentEl.style.cursor = "";
 
14293
        }
 
14294
    });
 
14295
 
 
14296
    event.addListener(el, "keyup", reset);
 
14297
    event.addListener(el, "blur", reset);
 
14298
    function reset() {
 
14299
        if (altCursor) {
 
14300
            contentEl.style.cursor = "";
 
14301
            altCursor = false;
 
14302
        }
 
14303
    }
 
14304
}
 
14305
 
 
14306
exports.MultiSelect = MultiSelect;
 
14307
 
 
14308
});
 
14309
 
 
14310
define('ace/mouse/multi_select_handler', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
 
14311
 
 
14312
var event = require("../lib/event");
 
14313
function isSamePoint(p1, p2) {
 
14314
    return p1.row == p2.row && p1.column == p2.column;
 
14315
}
 
14316
 
 
14317
function onMouseDown(e) {
 
14318
    var ev = e.domEvent;
 
14319
    var alt = ev.altKey;
 
14320
    var shift = ev.shiftKey;
 
14321
    var ctrl = e.getAccelKey();
 
14322
    var button = e.getButton();
 
14323
 
 
14324
    if (e.editor.inMultiSelectMode && button == 2) {
 
14325
        e.editor.textInput.onContextMenu(e.domEvent);
 
14326
        return;
 
14327
    }
 
14328
    
 
14329
    if (!ctrl && !alt) {
 
14330
        if (button == 0 && e.editor.inMultiSelectMode)
 
14331
            e.editor.exitMultiSelectMode();
 
14332
        return;
 
14333
    }
 
14334
 
 
14335
    var editor = e.editor;
 
14336
    var selection = editor.selection;
 
14337
    var isMultiSelect = editor.inMultiSelectMode;
 
14338
    var pos = e.getDocumentPosition();
 
14339
    var cursor = selection.getCursor();
 
14340
    var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
 
14341
 
 
14342
 
 
14343
    var mouseX = e.x, mouseY = e.y;
 
14344
    var onMouseSelection = function(e) {
 
14345
        mouseX = e.clientX;
 
14346
        mouseY = e.clientY;
 
14347
    };
 
14348
 
 
14349
    var blockSelect = function() {
 
14350
        var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
 
14351
        var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
 
14352
 
 
14353
        if (isSamePoint(screenCursor, newCursor)
 
14354
            && isSamePoint(cursor, selection.selectionLead))
 
14355
            return;
 
14356
        screenCursor = newCursor;
 
14357
 
 
14358
        editor.selection.moveCursorToPosition(cursor);
 
14359
        editor.selection.clearSelection();
 
14360
        editor.renderer.scrollCursorIntoView();
 
14361
 
 
14362
        editor.removeSelectionMarkers(rectSel);
 
14363
        rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
 
14364
        rectSel.forEach(editor.addSelectionMarker, editor);
 
14365
        editor.updateSelectionMarkers();
 
14366
    };
 
14367
    
 
14368
    var session = editor.session;
 
14369
    var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
 
14370
    var screenCursor = screenAnchor;
 
14371
 
 
14372
    
 
14373
 
 
14374
    if (ctrl && !shift && !alt && button == 0) {
 
14375
        if (!isMultiSelect && inSelection)
 
14376
            return; // dragging
 
14377
 
 
14378
        if (!isMultiSelect) {
 
14379
            var range = selection.toOrientedRange();
 
14380
            editor.addSelectionMarker(range);
 
14381
        }
 
14382
 
 
14383
        var oldRange = selection.rangeList.rangeAtPoint(pos);
 
14384
 
 
14385
        event.capture(editor.container, function(){}, function() {
 
14386
            var tmpSel = selection.toOrientedRange();
 
14387
 
 
14388
            if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
 
14389
                selection.substractPoint(tmpSel.cursor);
 
14390
            else {
 
14391
                if (range) {
 
14392
                    editor.removeSelectionMarker(range);
 
14393
                    selection.addRange(range);
 
14394
                }
 
14395
                selection.addRange(tmpSel);
 
14396
            }
 
14397
        });
 
14398
 
 
14399
    } else if (alt && button == 0) {
 
14400
        e.stop();
 
14401
 
 
14402
        if (isMultiSelect && !ctrl)
 
14403
            selection.toSingleRange();
 
14404
        else if (!isMultiSelect && ctrl)
 
14405
            selection.addRange();
 
14406
 
 
14407
        var rectSel = [];
 
14408
        if (shift) {
 
14409
            screenAnchor = session.documentToScreenPosition(selection.lead);
 
14410
            blockSelect();
 
14411
        } else {
 
14412
            selection.moveCursorToPosition(pos);
 
14413
            selection.clearSelection();
 
14414
        }
 
14415
 
 
14416
 
 
14417
        var onMouseSelectionEnd = function(e) {
 
14418
            clearInterval(timerId);
 
14419
            editor.removeSelectionMarkers(rectSel);
 
14420
            for (var i = 0; i < rectSel.length; i++)
 
14421
                selection.addRange(rectSel[i]);
 
14422
        };
 
14423
 
 
14424
        var onSelectionInterval = blockSelect;
 
14425
 
 
14426
        event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
 
14427
        var timerId = setInterval(function() {onSelectionInterval();}, 20);
 
14428
 
 
14429
        return e.preventDefault();
 
14430
    }
 
14431
}
 
14432
 
 
14433
 
 
14434
exports.onMouseDown = onMouseDown;
 
14435
 
 
14436
});
 
14437
 
 
14438
define('ace/commands/multi_select_commands', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler'], function(require, exports, module) {
 
14439
exports.defaultCommands = [{
 
14440
    name: "addCursorAbove",
 
14441
    exec: function(editor) { editor.selectMoreLines(-1); },
 
14442
    bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
 
14443
    readonly: true
 
14444
}, {
 
14445
    name: "addCursorBelow",
 
14446
    exec: function(editor) { editor.selectMoreLines(1); },
 
14447
    bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
 
14448
    readonly: true
 
14449
}, {
 
14450
    name: "addCursorAboveSkipCurrent",
 
14451
    exec: function(editor) { editor.selectMoreLines(-1, true); },
 
14452
    bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
 
14453
    readonly: true
 
14454
}, {
 
14455
    name: "addCursorBelowSkipCurrent",
 
14456
    exec: function(editor) { editor.selectMoreLines(1, true); },
 
14457
    bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
 
14458
    readonly: true
 
14459
}, {
 
14460
    name: "selectMoreBefore",
 
14461
    exec: function(editor) { editor.selectMore(-1); },
 
14462
    bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
 
14463
    readonly: true
 
14464
}, {
 
14465
    name: "selectMoreAfter",
 
14466
    exec: function(editor) { editor.selectMore(1); },
 
14467
    bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
 
14468
    readonly: true
 
14469
}, {
 
14470
    name: "selectNextBefore",
 
14471
    exec: function(editor) { editor.selectMore(-1, true); },
 
14472
    bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
 
14473
    readonly: true
 
14474
}, {
 
14475
    name: "selectNextAfter",
 
14476
    exec: function(editor) { editor.selectMore(1, true); },
 
14477
    bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
 
14478
    readonly: true
 
14479
}, {
 
14480
    name: "splitIntoLines",
 
14481
    exec: function(editor) { editor.multiSelect.splitIntoLines(); },
 
14482
    bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
 
14483
    readonly: true
 
14484
}, {
 
14485
    name: "alignCursors",
 
14486
    exec: function(editor) { editor.alignCursors(); },
 
14487
    bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"}
 
14488
}];
 
14489
exports.multiSelectCommands = [{
 
14490
    name: "singleSelection",
 
14491
    bindKey: "esc",
 
14492
    exec: function(editor) { editor.exitMultiSelectMode(); },
 
14493
    readonly: true,
 
14494
    isAvailable: function(editor) {return editor && editor.inMultiSelectMode}
 
14495
}];
 
14496
 
 
14497
var HashHandler = require("../keyboard/hash_handler").HashHandler;
 
14498
exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
 
14499
 
 
14500
});
 
14501
 
 
14502
define('ace/worker/worker_client', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/config'], function(require, exports, module) {
 
14503
 
 
14504
 
 
14505
var oop = require("../lib/oop");
 
14506
var EventEmitter = require("../lib/event_emitter").EventEmitter;
 
14507
var config = require("../config");
 
14508
 
 
14509
var WorkerClient = function(topLevelNamespaces, mod, classname) {
 
14510
    this.changeListener = this.changeListener.bind(this);
 
14511
    this.onMessage = this.onMessage.bind(this);
 
14512
    this.onError = this.onError.bind(this);
 
14513
 
 
14514
    var workerUrl;
 
14515
    if (config.get("packaged")) {
 
14516
        workerUrl = config.moduleUrl(mod, "worker");
 
14517
    } else {
 
14518
        var normalizePath = this.$normalizePath;
 
14519
        if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
 
14520
            workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
 
14521
        } else {
 
14522
            if (require.nameToUrl && !require.toUrl)
 
14523
                require.toUrl = require.nameToUrl;
 
14524
            workerUrl = normalizePath(require.toUrl("ace/worker/worker", null, "_"));
 
14525
        }
 
14526
 
 
14527
        var tlns = {};
 
14528
        topLevelNamespaces.forEach(function(ns) {
 
14529
            tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/.js(\?.*)?$/, ""));
 
14530
        });
 
14531
    }
 
14532
 
 
14533
    this.$worker = new Worker(workerUrl);
 
14534
    this.$worker.postMessage({
 
14535
        init : true,
 
14536
        tlns: tlns,
 
14537
        module: mod,
 
14538
        classname: classname
 
14539
    });
 
14540
 
 
14541
    this.callbackId = 1;
 
14542
    this.callbacks = {};
 
14543
 
 
14544
    this.$worker.onerror = this.onError;
 
14545
    this.$worker.onmessage = this.onMessage;
 
14546
};
 
14547
 
 
14548
(function(){
 
14549
 
 
14550
    oop.implement(this, EventEmitter);
 
14551
 
 
14552
    this.onError = function(e) {
 
14553
        window.console && console.log && console.log(e);
 
14554
        throw e;
 
14555
    };
 
14556
 
 
14557
    this.onMessage = function(e) {
 
14558
        var msg = e.data;
 
14559
        switch(msg.type) {
 
14560
            case "log":
 
14561
                window.console && console.log && console.log.apply(console, msg.data);
 
14562
                break;
 
14563
 
 
14564
            case "event":
 
14565
                this._emit(msg.name, {data: msg.data});
 
14566
                break;
 
14567
 
 
14568
            case "call":
 
14569
                var callback = this.callbacks[msg.id];
 
14570
                if (callback) {
 
14571
                    callback(msg.data);
 
14572
                    delete this.callbacks[msg.id];
 
14573
                }
 
14574
                break;
 
14575
        }
 
14576
    };
 
14577
 
 
14578
    this.$normalizePath = function(path) {
 
14579
        if (!location.host) // needed for file:// protocol
 
14580
            return path;
 
14581
        path = path.replace(/^[a-z]+:\/\/[^\/]+/, ""); // Remove domain name and rebuild it
 
14582
        path = location.protocol + "//" + location.host
 
14583
            + (path.charAt(0) == "/" ? "" : location.pathname.replace(/\/[^\/]*$/, ""))
 
14584
            + "/" + path.replace(/^[\/]+/, "");
 
14585
        return path;
 
14586
    };
 
14587
 
 
14588
    this.terminate = function() {
 
14589
        this._emit("terminate", {});
 
14590
        this.$worker.terminate();
 
14591
        this.$worker = null;
 
14592
        this.$doc.removeEventListener("change", this.changeListener);
 
14593
        this.$doc = null;
 
14594
    };
 
14595
 
 
14596
    this.send = function(cmd, args) {
 
14597
        this.$worker.postMessage({command: cmd, args: args});
 
14598
    };
 
14599
 
 
14600
    this.call = function(cmd, args, callback) {
 
14601
        if (callback) {
 
14602
            var id = this.callbackId++;
 
14603
            this.callbacks[id] = callback;
 
14604
            args.push(id);
 
14605
        }
 
14606
        this.send(cmd, args);
 
14607
    };
 
14608
 
 
14609
    this.emit = function(event, data) {
 
14610
        try {
 
14611
            this.$worker.postMessage({event: event, data: {data: data.data}});
 
14612
        }
 
14613
        catch(ex) {}
 
14614
    };
 
14615
 
 
14616
    this.attachToDocument = function(doc) {
 
14617
        if(this.$doc)
 
14618
            this.terminate();
 
14619
 
 
14620
        this.$doc = doc;
 
14621
        this.call("setValue", [doc.getValue()]);
 
14622
        doc.on("change", this.changeListener);
 
14623
    };
 
14624
 
 
14625
    this.changeListener = function(e) {
 
14626
        e.range = {
 
14627
            start: e.data.range.start,
 
14628
            end: e.data.range.end
 
14629
        };
 
14630
        this.emit("change", e);
 
14631
    };
 
14632
 
 
14633
}).call(WorkerClient.prototype);
 
14634
 
 
14635
 
 
14636
var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
 
14637
    this.changeListener = this.changeListener.bind(this);
 
14638
    this.callbackId = 1;
 
14639
    this.callbacks = {};
 
14640
    this.messageBuffer = [];
 
14641
 
 
14642
    var main = null;
 
14643
    var sender = Object.create(EventEmitter);
 
14644
    var _self = this;
 
14645
 
 
14646
    this.$worker = {}
 
14647
    this.$worker.terminate = function() {};
 
14648
    this.$worker.postMessage = function(e) {
 
14649
        _self.messageBuffer.push(e);
 
14650
        main && setTimeout(processNext);
 
14651
    };
 
14652
 
 
14653
    var processNext = function() {
 
14654
        var msg = _self.messageBuffer.shift();
 
14655
        if (msg.command)
 
14656
            main[msg.command].apply(main, msg.args);
 
14657
        else if (msg.event)
 
14658
            sender._emit(msg.event, msg.data);
 
14659
    };
 
14660
 
 
14661
    sender.postMessage = function(msg) {
 
14662
        _self.onMessage({data: msg});
 
14663
    };
 
14664
    sender.callback = function(data, callbackId) {
 
14665
        this.postMessage({type: "call", id: callbackId, data: data});
 
14666
    };
 
14667
    sender.emit = function(name, data) {
 
14668
        this.postMessage({type: "event", name: name, data: data});
 
14669
    };
 
14670
 
 
14671
    config.loadModule(["worker", mod], function(Main) {
 
14672
        main = new Main[classname](sender);
 
14673
        while (_self.messageBuffer.length)
 
14674
            processNext();
 
14675
    });
 
14676
};
 
14677
 
 
14678
UIWorkerClient.prototype = WorkerClient.prototype;
 
14679
 
 
14680
exports.UIWorkerClient = UIWorkerClient;
 
14681
exports.WorkerClient = WorkerClient;
 
14682
 
 
14683
});
 
14684
define('ace/placeholder', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/event_emitter', 'ace/lib/oop'], function(require, exports, module) {
 
14685
 
 
14686
 
 
14687
var Range = require("./range").Range;
 
14688
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
14689
var oop = require("./lib/oop");
 
14690
 
 
14691
var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {
 
14692
    var _self = this;
 
14693
    this.length = length;
 
14694
    this.session = session;
 
14695
    this.doc = session.getDocument();
 
14696
    this.mainClass = mainClass;
 
14697
    this.othersClass = othersClass;
 
14698
    this.$onUpdate = this.onUpdate.bind(this);
 
14699
    this.doc.on("change", this.$onUpdate);
 
14700
    this.$others = others;
 
14701
    
 
14702
    this.$onCursorChange = function() {
 
14703
        setTimeout(function() {
 
14704
            _self.onCursorChange();
 
14705
        });
 
14706
    };
 
14707
    
 
14708
    this.$pos = pos;
 
14709
    var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};
 
14710
    this.$undoStackDepth =  undoStack.length;
 
14711
    this.setup();
 
14712
 
 
14713
    session.selection.on("changeCursor", this.$onCursorChange);
 
14714
};
 
14715
 
 
14716
(function() {
 
14717
 
 
14718
    oop.implement(this, EventEmitter);
 
14719
    this.setup = function() {
 
14720
        var _self = this;
 
14721
        var doc = this.doc;
 
14722
        var session = this.session;
 
14723
        var pos = this.$pos;
 
14724
 
 
14725
        this.pos = doc.createAnchor(pos.row, pos.column);
 
14726
        this.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
 
14727
        this.pos.on("change", function(event) {
 
14728
            session.removeMarker(_self.markerId);
 
14729
            _self.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.mainClass, null, false);
 
14730
        });
 
14731
        this.others = [];
 
14732
        this.$others.forEach(function(other) {
 
14733
            var anchor = doc.createAnchor(other.row, other.column);
 
14734
            _self.others.push(anchor);
 
14735
        });
 
14736
        session.setUndoSelect(false);
 
14737
    };
 
14738
    this.showOtherMarkers = function() {
 
14739
        if(this.othersActive) return;
 
14740
        var session = this.session;
 
14741
        var _self = this;
 
14742
        this.othersActive = true;
 
14743
        this.others.forEach(function(anchor) {
 
14744
            anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);
 
14745
            anchor.on("change", function(event) {
 
14746
                session.removeMarker(anchor.markerId);
 
14747
                anchor.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.othersClass, null, false);
 
14748
            });
 
14749
        });
 
14750
    };
 
14751
    this.hideOtherMarkers = function() {
 
14752
        if(!this.othersActive) return;
 
14753
        this.othersActive = false;
 
14754
        for (var i = 0; i < this.others.length; i++) {
 
14755
            this.session.removeMarker(this.others[i].markerId);
 
14756
        }
 
14757
    };
 
14758
    this.onUpdate = function(event) {
 
14759
        var delta = event.data;
 
14760
        var range = delta.range;
 
14761
        if(range.start.row !== range.end.row) return;
 
14762
        if(range.start.row !== this.pos.row) return;
 
14763
        if (this.$updating) return;
 
14764
        this.$updating = true;
 
14765
        var lengthDiff = delta.action === "insertText" ? range.end.column - range.start.column : range.start.column - range.end.column;
 
14766
        
 
14767
        if(range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1) {
 
14768
            var distanceFromStart = range.start.column - this.pos.column;
 
14769
            this.length += lengthDiff;
 
14770
            if(!this.session.$fromUndo) {
 
14771
                if(delta.action === "insertText") {
 
14772
                    for (var i = this.others.length - 1; i >= 0; i--) {
 
14773
                        var otherPos = this.others[i];
 
14774
                        var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
 
14775
                        if(otherPos.row === range.start.row && range.start.column < otherPos.column)
 
14776
                            newPos.column += lengthDiff;
 
14777
                        this.doc.insert(newPos, delta.text);
 
14778
                    }
 
14779
                } else if(delta.action === "removeText") {
 
14780
                    for (var i = this.others.length - 1; i >= 0; i--) {
 
14781
                        var otherPos = this.others[i];
 
14782
                        var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
 
14783
                        if(otherPos.row === range.start.row && range.start.column < otherPos.column)
 
14784
                            newPos.column += lengthDiff;
 
14785
                        this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));
 
14786
                    }
 
14787
                }
 
14788
                if(range.start.column === this.pos.column && delta.action === "insertText") {
 
14789
                    setTimeout(function() {
 
14790
                        this.pos.setPosition(this.pos.row, this.pos.column - lengthDiff);
 
14791
                        for (var i = 0; i < this.others.length; i++) {
 
14792
                            var other = this.others[i];
 
14793
                            var newPos = {row: other.row, column: other.column - lengthDiff};
 
14794
                            if(other.row === range.start.row && range.start.column < other.column)
 
14795
                                newPos.column += lengthDiff;
 
14796
                            other.setPosition(newPos.row, newPos.column);
 
14797
                        }
 
14798
                    }.bind(this), 0);
 
14799
                }
 
14800
                else if(range.start.column === this.pos.column && delta.action === "removeText") {
 
14801
                    setTimeout(function() {
 
14802
                        for (var i = 0; i < this.others.length; i++) {
 
14803
                            var other = this.others[i];
 
14804
                            if(other.row === range.start.row && range.start.column < other.column) {
 
14805
                                other.setPosition(other.row, other.column - lengthDiff);
 
14806
                            }
 
14807
                        }
 
14808
                    }.bind(this), 0);
 
14809
                }
 
14810
            }
 
14811
            this.pos._emit("change", {value: this.pos});
 
14812
            for (var i = 0; i < this.others.length; i++) {
 
14813
                this.others[i]._emit("change", {value: this.others[i]});
 
14814
            }
 
14815
        }
 
14816
        this.$updating = false;
 
14817
    };
 
14818
 
 
14819
    this.onCursorChange = function(event) {
 
14820
        if (this.$updating) return;
 
14821
        var pos = this.session.selection.getCursor();
 
14822
        if(pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
 
14823
            this.showOtherMarkers();
 
14824
            this._emit("cursorEnter", event);
 
14825
        } else {
 
14826
            this.hideOtherMarkers();
 
14827
            this._emit("cursorLeave", event);
 
14828
        }
 
14829
    };    
 
14830
    this.detach = function() {
 
14831
        this.session.removeMarker(this.markerId);
 
14832
        this.hideOtherMarkers();
 
14833
        this.doc.removeEventListener("change", this.$onUpdate);
 
14834
        this.session.selection.removeEventListener("changeCursor", this.$onCursorChange);
 
14835
        this.pos.detach();
 
14836
        for (var i = 0; i < this.others.length; i++) {
 
14837
            this.others[i].detach();
 
14838
        }
 
14839
        this.session.setUndoSelect(true);
 
14840
    };
 
14841
    this.cancel = function() {
 
14842
        if(this.$undoStackDepth === -1)
 
14843
            throw Error("Canceling placeholders only supported with undo manager attached to session.");
 
14844
        var undoManager = this.session.getUndoManager();
 
14845
        var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;
 
14846
        for (var i = 0; i < undosRequired; i++) {
 
14847
            undoManager.undo(true);
 
14848
        }
 
14849
    };
 
14850
}).call(PlaceHolder.prototype);
 
14851
 
 
14852
 
 
14853
exports.PlaceHolder = PlaceHolder;
 
14854
});
 
14855
 
 
14856
define('ace/mode/folding/fold_mode', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
 
14857
 
 
14858
 
 
14859
var Range = require("../../range").Range;
 
14860
 
 
14861
var FoldMode = exports.FoldMode = function() {};
 
14862
 
 
14863
(function() {
 
14864
 
 
14865
    this.foldingStartMarker = null;
 
14866
    this.foldingStopMarker = null;
 
14867
    this.getFoldWidget = function(session, foldStyle, row) {
 
14868
        var line = session.getLine(row);
 
14869
        if (this.foldingStartMarker.test(line))
 
14870
            return "start";
 
14871
        if (foldStyle == "markbeginend"
 
14872
                && this.foldingStopMarker
 
14873
                && this.foldingStopMarker.test(line))
 
14874
            return "end";
 
14875
        return "";
 
14876
    };
 
14877
 
 
14878
    this.getFoldWidgetRange = function(session, foldStyle, row) {
 
14879
        return null;
 
14880
    };
 
14881
 
 
14882
    this.indentationBlock = function(session, row, column) {
 
14883
        var re = /\S/;
 
14884
        var line = session.getLine(row);
 
14885
        var startLevel = line.search(re);
 
14886
        if (startLevel == -1)
 
14887
            return;
 
14888
 
 
14889
        var startColumn = column || line.length;
 
14890
        var maxRow = session.getLength();
 
14891
        var startRow = row;
 
14892
        var endRow = row;
 
14893
 
 
14894
        while (++row < maxRow) {
 
14895
            var level = session.getLine(row).search(re);
 
14896
 
 
14897
            if (level == -1)
 
14898
                continue;
 
14899
 
 
14900
            if (level <= startLevel)
 
14901
                break;
 
14902
 
 
14903
            endRow = row;
 
14904
        }
 
14905
 
 
14906
        if (endRow > startRow) {
 
14907
            var endColumn = session.getLine(endRow).length;
 
14908
            return new Range(startRow, startColumn, endRow, endColumn);
 
14909
        }
 
14910
    };
 
14911
 
 
14912
    this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
 
14913
        var start = {row: row, column: column + 1};
 
14914
        var end = session.$findClosingBracket(bracket, start, typeRe);
 
14915
        if (!end)
 
14916
            return;
 
14917
 
 
14918
        var fw = session.foldWidgets[end.row];
 
14919
        if (fw == null)
 
14920
            fw = this.getFoldWidget(session, end.row);
 
14921
 
 
14922
        if (fw == "start" && end.row > start.row) {
 
14923
            end.row --;
 
14924
            end.column = session.getLine(end.row).length;
 
14925
        }
 
14926
        return Range.fromPoints(start, end);
 
14927
    };
 
14928
 
 
14929
    this.closingBracketBlock = function(session, bracket, row, column, typeRe) {
 
14930
        var end = {row: row, column: column};
 
14931
        var start = session.$findOpeningBracket(bracket, end);
 
14932
 
 
14933
        if (!start)
 
14934
            return;
 
14935
 
 
14936
        start.column++;
 
14937
        end.column--;
 
14938
 
 
14939
        return  Range.fromPoints(start, end);
 
14940
    };
 
14941
}).call(FoldMode.prototype);
 
14942
 
 
14943
});
 
14944
 
 
14945
define('ace/theme/textmate', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
 
14946
 
 
14947
 
 
14948
exports.isDark = false;
 
14949
exports.cssClass = "ace-tm";
 
14950
exports.cssText = ".ace-tm .ace_gutter {\
 
14951
background: #f0f0f0;\
 
14952
color: #333;\
 
14953
}\
 
14954
.ace-tm .ace_print-margin {\
 
14955
width: 1px;\
 
14956
background: #e8e8e8;\
 
14957
}\
 
14958
.ace-tm .ace_fold {\
 
14959
background-color: #6B72E6;\
 
14960
}\
 
14961
.ace-tm .ace_scroller {\
 
14962
background-color: #FFFFFF;\
 
14963
}\
 
14964
.ace-tm .ace_cursor {\
 
14965
border-left: 2px solid black;\
 
14966
}\
 
14967
.ace-tm .ace_overwrite-cursors .ace_cursor {\
 
14968
border-left: 0px;\
 
14969
border-bottom: 1px solid black;\
 
14970
}\
 
14971
.ace-tm .ace_invisible {\
 
14972
color: rgb(191, 191, 191);\
 
14973
}\
 
14974
.ace-tm .ace_storage,\
 
14975
.ace-tm .ace_keyword {\
 
14976
color: blue;\
 
14977
}\
 
14978
.ace-tm .ace_constant {\
 
14979
color: rgb(197, 6, 11);\
 
14980
}\
 
14981
.ace-tm .ace_constant.ace_buildin {\
 
14982
color: rgb(88, 72, 246);\
 
14983
}\
 
14984
.ace-tm .ace_constant.ace_language {\
 
14985
color: rgb(88, 92, 246);\
 
14986
}\
 
14987
.ace-tm .ace_constant.ace_library {\
 
14988
color: rgb(6, 150, 14);\
 
14989
}\
 
14990
.ace-tm .ace_invalid {\
 
14991
background-color: rgba(255, 0, 0, 0.1);\
 
14992
color: red;\
 
14993
}\
 
14994
.ace-tm .ace_support.ace_function {\
 
14995
color: rgb(60, 76, 114);\
 
14996
}\
 
14997
.ace-tm .ace_support.ace_constant {\
 
14998
color: rgb(6, 150, 14);\
 
14999
}\
 
15000
.ace-tm .ace_support.ace_type,\
 
15001
.ace-tm .ace_support.ace_class {\
 
15002
color: rgb(109, 121, 222);\
 
15003
}\
 
15004
.ace-tm .ace_keyword.ace_operator {\
 
15005
color: rgb(104, 118, 135);\
 
15006
}\
 
15007
.ace-tm .ace_string {\
 
15008
color: rgb(3, 106, 7);\
 
15009
}\
 
15010
.ace-tm .ace_comment {\
 
15011
color: rgb(76, 136, 107);\
 
15012
}\
 
15013
.ace-tm .ace_comment.ace_doc {\
 
15014
color: rgb(0, 102, 255);\
 
15015
}\
 
15016
.ace-tm .ace_comment.ace_doc.ace_tag {\
 
15017
color: rgb(128, 159, 191);\
 
15018
}\
 
15019
.ace-tm .ace_constant.ace_numeric {\
 
15020
color: rgb(0, 0, 205);\
 
15021
}\
 
15022
.ace-tm .ace_variable {\
 
15023
color: rgb(49, 132, 149);\
 
15024
}\
 
15025
.ace-tm .ace_xml-pe {\
 
15026
color: rgb(104, 104, 91);\
 
15027
}\
 
15028
.ace-tm .ace_entity.ace_name.ace_function {\
 
15029
color: #0000A2;\
 
15030
}\
 
15031
.ace-tm .ace_markup.ace_heading {\
 
15032
color: rgb(12, 7, 255);\
 
15033
}\
 
15034
.ace-tm .ace_markup.ace_list {\
 
15035
color:rgb(185, 6, 144);\
 
15036
}\
 
15037
.ace-tm .ace_meta.ace_tag {\
 
15038
color:rgb(0, 22, 142);\
 
15039
}\
 
15040
.ace-tm .ace_string.ace_regex {\
 
15041
color: rgb(255, 0, 0)\
 
15042
}\
 
15043
.ace-tm .ace_marker-layer .ace_selection {\
 
15044
background: rgb(181, 213, 255);\
 
15045
}\
 
15046
.ace-tm.ace_multiselect .ace_selection.ace_start {\
 
15047
box-shadow: 0 0 3px 0px white;\
 
15048
border-radius: 2px;\
 
15049
}\
 
15050
.ace-tm .ace_marker-layer .ace_step {\
 
15051
background: rgb(252, 255, 0);\
 
15052
}\
 
15053
.ace-tm .ace_marker-layer .ace_stack {\
 
15054
background: rgb(164, 229, 101);\
 
15055
}\
 
15056
.ace-tm .ace_marker-layer .ace_bracket {\
 
15057
margin: -1px 0 0 -1px;\
 
15058
border: 1px solid rgb(192, 192, 192);\
 
15059
}\
 
15060
.ace-tm .ace_marker-layer .ace_active-line {\
 
15061
background: rgba(0, 0, 0, 0.07);\
 
15062
}\
 
15063
.ace-tm .ace_gutter-active-line {\
 
15064
background-color : #dcdcdc;\
 
15065
}\
 
15066
.ace-tm .ace_marker-layer .ace_selected-word {\
 
15067
background: rgb(250, 250, 255);\
 
15068
border: 1px solid rgb(200, 200, 250);\
 
15069
}\
 
15070
.ace-tm .ace_indent-guide {\
 
15071
background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
 
15072
}\
 
15073
";
 
15074
 
 
15075
var dom = require("../lib/dom");
 
15076
dom.importCssString(exports.cssText, exports.cssClass);
 
15077
});
 
15078
;
 
15079
            (function() {
 
15080
                window.require(["ace/ace"], function(a) {
 
15081
                    a && a.config.init();
 
15082
                    if (!window.ace)
 
15083
                        window.ace = {};
 
15084
                    for (var key in a) if (a.hasOwnProperty(key))
 
15085
                        ace[key] = a[key];
 
15086
                });
 
15087
            })();
 
15088
        
 
 
b'\\ No newline at end of file'