You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ro...@apache.org on 2015/03/23 13:07:24 UTC

[50/52] [partial] fauxton commit: updated refs/heads/master to 2222dcd

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/067b0880/assets/js/libs/ace/ace.js
----------------------------------------------------------------------
diff --git a/assets/js/libs/ace/ace.js b/assets/js/libs/ace/ace.js
index eda1067..e0aad98 100644
--- a/assets/js/libs/ace/ace.js
+++ b/assets/js/libs/ace/ace.js
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2010, Ajax.org B.V.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
  *     * Redistributions of source code must retain the above copyright
@@ -14,7 +14,7 @@
  *     * Neither the name of Ajax.org B.V. nor the
  *       names of its contributors may be used to endorse or promote products
  *       derived from this software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -28,6 +28,12 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+/**
+ * Define a module along with a payload
+ * @param module a name for the payload
+ * @param payload a function to call with (require, exports, module) params
+ */
+
 (function() {
 
 var ACE_NAMESPACE = "";
@@ -59,10 +65,14 @@ var _define = function(module, deps, payload) {
         _define.modules = {};
         _define.payloads = {};
     }
-    
+
     _define.payloads[module] = payload;
     _define.modules[module] = null;
 };
+
+/**
+ * Get at functionality define()ed using the function above
+ */
 var _require = function(parentId, module, callback) {
     if (Object.prototype.toString.call(module) === "[object Array]") {
         var params = [];
@@ -94,10 +104,12 @@ var _require = function(parentId, module, callback) {
 };
 
 var normalizeModule = function(parentId, moduleName) {
+    // normalize plugin requires
     if (moduleName.indexOf("!") !== -1) {
         var chunks = moduleName.split("!");
         return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
     }
+    // normalize relative requires
     if (moduleName.charAt(0) == ".") {
         var base = parentId.split("/").slice(0, -1).join("/");
         moduleName = base + "/" + moduleName;
@@ -110,6 +122,11 @@ var normalizeModule = function(parentId, moduleName) {
 
     return moduleName;
 };
+
+/**
+ * Internal function to lookup moduleNames and resolve them by calling the
+ * definition function if needed.
+ */
 var lookup = function(parentId, moduleName) {
 
     moduleName = normalizeModule(parentId, moduleName);
@@ -143,7 +160,7 @@ var lookup = function(parentId, moduleName) {
 function exportAce(ns) {
     var require = function(module, callback) {
         return _require("", module, callback);
-    };    
+    };
 
     var root = global;
     if (ns) {
@@ -169,16 +186,8 @@ exportAce(ACE_NAMESPACE);
 
 })();
 
-
-define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
-
-
-require("./regexp");
-require("./es5-shim");
-
-});
- 
-define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
+define("ace/lib/regexp",["require","exports","module"], function(require, exports, module) {
+"use strict";
 
     var real = {
             exec: RegExp.prototype.exec,
@@ -250,7 +259,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
 
 });
 
-define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
+define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) {
 
 function Empty() {}
 
@@ -947,11 +956,16 @@ var toObject = function (o) {
 
 });
 
-define('ace/lib/dom', ['require', 'exports', 'module' ], function(require, exports, module) {
+define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"], function(require, exports, module) {
+"use strict";
 
+require("./regexp");
+require("./es5-shim");
 
-if (typeof document == "undefined")
-    return;
+});
+
+define("ace/lib/dom",["require","exports","module"], function(require, exports, module) {
+"use strict";
 
 var XHTML_NS = "http://www.w3.org/1999/xhtml";
 
@@ -968,7 +982,7 @@ exports.createElement = function(tag, ns) {
 };
 
 exports.hasCssClass = function(el, name) {
-    var classes = el.className.split(/\s+/g);
+    var classes = (el.className || "").split(/\s+/g);
     return classes.indexOf(name) !== -1;
 };
 exports.addCssClass = function(el, name) {
@@ -1080,6 +1094,10 @@ exports.getInnerHeight = function(element) {
     );
 };
 
+
+if (typeof document == "undefined")
+    return;
+
 if (window.pageYOffset !== undefined) {
     exports.getPageScrollTop = function() {
         return window.pageYOffset;
@@ -1180,12 +1198,201 @@ exports.getParentWindow = function(document) {
 
 });
 
-define('ace/lib/event', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/useragent', 'ace/lib/dom'], function(require, exports, module) {
+define("ace/lib/oop",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+exports.inherits = function(ctor, superCtor) {
+    ctor.super_ = superCtor;
+    ctor.prototype = Object.create(superCtor.prototype, {
+        constructor: {
+            value: ctor,
+            enumerable: false,
+            writable: true,
+            configurable: true
+        }
+    });
+};
+
+exports.mixin = function(obj, mixin) {
+    for (var key in mixin) {
+        obj[key] = mixin[key];
+    }
+    return obj;
+};
+
+exports.implement = function(proto, mixin) {
+    exports.mixin(proto, mixin);
+};
+
+});
+
+define("ace/lib/keys",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop"], function(require, exports, module) {
+"use strict";
+
+require("./fixoldbrowsers");
+
+var oop = require("./oop");
+var Keys = (function() {
+    var ret = {
+        MODIFIER_KEYS: {
+            16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
+        },
+
+        KEY_MODS: {
+            "ctrl": 1, "alt": 2, "option" : 2, "shift": 4,
+            "super": 8, "meta": 8, "command": 8, "cmd": 8
+        },
+
+        FUNCTION_KEYS : {
+            8  : "Backspace",
+            9  : "Tab",
+            13 : "Return",
+            19 : "Pause",
+            27 : "Esc",
+            32 : "Space",
+            33 : "PageUp",
+            34 : "PageDown",
+            35 : "End",
+            36 : "Home",
+            37 : "Left",
+            38 : "Up",
+            39 : "Right",
+            40 : "Down",
+            44 : "Print",
+            45 : "Insert",
+            46 : "Delete",
+            96 : "Numpad0",
+            97 : "Numpad1",
+            98 : "Numpad2",
+            99 : "Numpad3",
+            100: "Numpad4",
+            101: "Numpad5",
+            102: "Numpad6",
+            103: "Numpad7",
+            104: "Numpad8",
+            105: "Numpad9",
+            '-13': "NumpadEnter",
+            112: "F1",
+            113: "F2",
+            114: "F3",
+            115: "F4",
+            116: "F5",
+            117: "F6",
+            118: "F7",
+            119: "F8",
+            120: "F9",
+            121: "F10",
+            122: "F11",
+            123: "F12",
+            144: "Numlock",
+            145: "Scrolllock"
+        },
+
+        PRINTABLE_KEYS: {
+           32: ' ',  48: '0',  49: '1',  50: '2',  51: '3',  52: '4', 53:  '5',
+           54: '6',  55: '7',  56: '8',  57: '9',  59: ';',  61: '=', 65:  'a',
+           66: 'b',  67: 'c',  68: 'd',  69: 'e',  70: 'f',  71: 'g', 72:  'h',
+           73: 'i',  74: 'j',  75: 'k',  76: 'l',  77: 'm',  78: 'n', 79:  'o',
+           80: 'p',  81: 'q',  82: 'r',  83: 's',  84: 't',  85: 'u', 86:  'v',
+           87: 'w',  88: 'x',  89: 'y',  90: 'z', 107: '+', 109: '-', 110: '.',
+          187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`', 219: '[',
+          220: '\\',221: ']', 222: '\''
+        }
+    };
+    var name, i;
+    for (i in ret.FUNCTION_KEYS) {
+        name = ret.FUNCTION_KEYS[i].toLowerCase();
+        ret[name] = parseInt(i, 10);
+    }
+    for (i in ret.PRINTABLE_KEYS) {
+        name = ret.PRINTABLE_KEYS[i].toLowerCase();
+        ret[name] = parseInt(i, 10);
+    }
+    oop.mixin(ret, ret.MODIFIER_KEYS);
+    oop.mixin(ret, ret.PRINTABLE_KEYS);
+    oop.mixin(ret, ret.FUNCTION_KEYS);
+    ret.enter = ret["return"];
+    ret.escape = ret.esc;
+    ret.del = ret["delete"];
+    ret[173] = '-';
+    
+    (function() {
+        var mods = ["cmd", "ctrl", "alt", "shift"];
+        for (var i = Math.pow(2, mods.length); i--;) {            
+            ret.KEY_MODS[i] = mods.filter(function(x) {
+                return i & ret.KEY_MODS[x];
+            }).join("-") + "-";
+        }
+    })();
+
+    ret.KEY_MODS[0] = "";
+    ret.KEY_MODS[-1] = "input";
+
+    return ret;
+})();
+oop.mixin(exports, Keys);
+
+exports.keyCodeToString = function(keyCode) {
+    var keyString = Keys[keyCode];
+    if (typeof keyString != "string")
+        keyString = String.fromCharCode(keyCode);
+    return keyString.toLowerCase();
+};
+
+});
+
+define("ace/lib/useragent",["require","exports","module"], function(require, exports, module) {
+"use strict";
+exports.OS = {
+    LINUX: "LINUX",
+    MAC: "MAC",
+    WINDOWS: "WINDOWS"
+};
+exports.getOS = function() {
+    if (exports.isMac) {
+        return exports.OS.MAC;
+    } else if (exports.isLinux) {
+        return exports.OS.LINUX;
+    } else {
+        return exports.OS.WINDOWS;
+    }
+};
+if (typeof navigator != "object")
+    return;
+
+var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
+var ua = navigator.userAgent;
+exports.isWin = (os == "win");
+exports.isMac = (os == "mac");
+exports.isLinux = (os == "linux");
+exports.isIE = 
+    (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
+    ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1])
+    : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie
+    
+exports.isOldIE = exports.isIE && exports.isIE < 9;
+exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko";
+exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv\:(\d+)/)||[])[1], 10) < 4;
+exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
+exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
+
+exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
+
+exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
+
+exports.isIPad = ua.indexOf("iPad") >= 0;
+
+exports.isTouchPad = ua.indexOf("TouchPad") >= 0;
+
+exports.isChromeOS = ua.indexOf(" CrOS ") >= 0;
 
+});
+
+define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) {
+"use strict";
 
 var keys = require("./keys");
 var useragent = require("./useragent");
-var dom = require("./dom");
 
 exports.addListener = function(elem, type, callback) {
     if (elem.addEventListener) {
@@ -1230,7 +1437,7 @@ exports.preventDefault = function(e) {
 exports.getButton = function(e) {
     if (e.type == "dblclick")
         return 0;
-    if (e.type == "contextmenu" || (e.ctrlKey && useragent.isMac))
+    if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))
         return 2;
     if (e.preventDefault) {
         return e.button;
@@ -1253,12 +1460,14 @@ exports.capture = function(el, eventHandler, releaseCaptureHandler) {
     exports.addListener(document, "mousemove", eventHandler, true);
     exports.addListener(document, "mouseup", onMouseUp, true);
     exports.addListener(document, "dragstart", onMouseUp, true);
+    
+    return onMouseUp;
 };
 
 exports.addMouseWheelListener = function(el, callback) {
     if ("onmousewheel" in el) {
-        var factor = 8;
         exports.addListener(el, "mousewheel", function(e) {
+            var factor = 8;
             if (e.wheelDeltaX !== undefined) {
                 e.wheelX = -e.wheelDeltaX / factor;
                 e.wheelY = -e.wheelDeltaY / factor;
@@ -1270,8 +1479,19 @@ exports.addMouseWheelListener = function(el, callback) {
         });
     } else if ("onwheel" in el) {
         exports.addListener(el, "wheel",  function(e) {
-            e.wheelX = (e.deltaX || 0) * 5;
-            e.wheelY = (e.deltaY || 0) * 5;
+            var factor = 0.35;
+            switch (e.deltaMode) {
+                case e.DOM_DELTA_PIXEL:
+                    e.wheelX = e.deltaX * factor || 0;
+                    e.wheelY = e.deltaY * factor || 0;
+                    break;
+                case e.DOM_DELTA_LINE:
+                case e.DOM_DELTA_PAGE:
+                    e.wheelX = (e.deltaX || 0) * 5;
+                    e.wheelY = (e.deltaY || 0) * 5;
+                    break;
+            }
+            
             callback(e);
         });
     } else {
@@ -1290,7 +1510,7 @@ exports.addMouseWheelListener = function(el, callback) {
 
 exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbackName) {
     var clicks = 0;
-    var startX, startY, timer;
+    var startX, startY, timer; 
     var eventNames = {
         2: "dblclick",
         3: "tripleclick",
@@ -1298,7 +1518,7 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac
     };
 
     exports.addListener(el, "mousedown", function(e) {
-        if (exports.getButton(e) != 0) {
+        if (exports.getButton(e) !== 0) {
             clicks = 0;
         } else if (e.detail > 1) {
             clicks++;
@@ -1309,14 +1529,19 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac
         }
         if (useragent.isIE) {
             var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;
-            if (isNewClick) {
+            if (!timer || isNewClick)
                 clicks = 1;
-            }
+            if (timer)
+                clearTimeout(timer);
+            timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
+
             if (clicks == 1) {
                 startX = e.clientX;
                 startY = e.clientY;
             }
         }
+        
+        e._clicks = clicks;
 
         eventHandler[callbackName]("mousedown", e);
 
@@ -1338,27 +1563,32 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac
     }
 };
 
-function normalizeCommandKeys(callback, e, keyCode) {
-    var hashId = 0;
-    if ((useragent.isOpera && !("KeyboardEvent" in window)) && useragent.isMac) {
-        hashId = 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0)
-            | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
-    } else {
-        hashId = 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0)
-            | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
+var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window)
+    ? function(e) {
+        return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
     }
+    : function(e) {
+        return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
+    };
+
+exports.getModifierString = function(e) {
+    return keys.KEY_MODS[getModifierHash(e)];
+};
+
+function normalizeCommandKeys(callback, e, keyCode) {
+    var hashId = getModifierHash(e);
 
     if (!useragent.isMac && pressedKeys) {
         if (pressedKeys[91] || pressedKeys[92])
             hashId |= 8;
         if (pressedKeys.altGr) {
             if ((3 & hashId) != 3)
-                pressedKeys.altGr = 0
+                pressedKeys.altGr = 0;
             else
                 return;
         }
         if (keyCode === 18 || keyCode === 17) {
-            var location = e.location || e.keyLocation;
+            var location = "location" in e ? e.location : e.keyLocation;
             if (keyCode === 17 && location === 1) {
                 ts = e.timeStamp;
             } else if (keyCode === 18 && hashId === 3 && location === 2) {
@@ -1386,26 +1616,33 @@ function normalizeCommandKeys(callback, e, keyCode) {
                 hashId = 8;
                 break;
         }
-        keyCode = 0;
+        keyCode = -1;
     }
 
     if (hashId & 8 && (keyCode === 91 || keyCode === 93)) {
-        keyCode = 0;
+        keyCode = -1;
     }
     
     if (!hashId && keyCode === 13) {
-        if (e.location || e.keyLocation === 3) {
-            callback(e, hashId, -keyCode)
+        var location = "location" in e ? e.location : e.keyLocation;
+        if (location === 3) {
+            callback(e, hashId, -keyCode);
             if (e.defaultPrevented)
                 return;
         }
     }
+    
+    if (useragent.isChromeOS && hashId & 8) {
+        callback(e, hashId, keyCode);
+        if (e.defaultPrevented)
+            return;
+        else
+            hashId &= ~8;
+    }
     if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {
         return false;
     }
     
-    
-    
     return callback(e, hashId, keyCode);
 }
 
@@ -1482,14778 +1719,15839 @@ else
     };
 });
 
-define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/lib/oop'], function(require, exports, module) {
+define("ace/lib/lang",["require","exports","module"], function(require, exports, module) {
+"use strict";
 
+exports.last = function(a) {
+    return a[a.length - 1];
+};
 
-var oop = require("./oop");
-var Keys = (function() {
-    var ret = {
-        MODIFIER_KEYS: {
-            16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
-        },
+exports.stringReverse = function(string) {
+    return string.split("").reverse().join("");
+};
 
-        KEY_MODS: {
-            "ctrl": 1, "alt": 2, "option" : 2,
-            "shift": 4, "meta": 8, "command": 8, "cmd": 8
-        },
+exports.stringRepeat = function (string, count) {
+    var result = '';
+    while (count > 0) {
+        if (count & 1)
+            result += string;
 
-        FUNCTION_KEYS : {
-            8  : "Backspace",
-            9  : "Tab",
-            13 : "Return",
-            19 : "Pause",
-            27 : "Esc",
-            32 : "Space",
-            33 : "PageUp",
-            34 : "PageDown",
-            35 : "End",
-            36 : "Home",
-            37 : "Left",
-            38 : "Up",
-            39 : "Right",
-            40 : "Down",
-            44 : "Print",
-            45 : "Insert",
-            46 : "Delete",
-            96 : "Numpad0",
-            97 : "Numpad1",
-            98 : "Numpad2",
-            99 : "Numpad3",
-            100: "Numpad4",
-            101: "Numpad5",
-            102: "Numpad6",
-            103: "Numpad7",
-            104: "Numpad8",
-            105: "Numpad9",
-            '-13': "NumpadEnter",
-            112: "F1",
-            113: "F2",
-            114: "F3",
-            115: "F4",
-            116: "F5",
-            117: "F6",
-            118: "F7",
-            119: "F8",
-            120: "F9",
-            121: "F10",
-            122: "F11",
-            123: "F12",
-            144: "Numlock",
-            145: "Scrolllock"
-        },
-
-        PRINTABLE_KEYS: {
-           32: ' ',  48: '0',  49: '1',  50: '2',  51: '3',  52: '4', 53:  '5',
-           54: '6',  55: '7',  56: '8',  57: '9',  59: ';',  61: '=', 65:  'a',
-           66: 'b',  67: 'c',  68: 'd',  69: 'e',  70: 'f',  71: 'g', 72:  'h',
-           73: 'i',  74: 'j',  75: 'k',  76: 'l',  77: 'm',  78: 'n', 79:  'o',
-           80: 'p',  81: 'q',  82: 'r',  83: 's',  84: 't',  85: 'u', 86:  'v',
-           87: 'w',  88: 'x',  89: 'y',  90: 'z', 107: '+', 109: '-', 110: '.',
-          188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
-          221: ']', 222: '\''
-        }
-    };
-    for (var i in ret.FUNCTION_KEYS) {
-        var name = ret.FUNCTION_KEYS[i].toLowerCase();
-        ret[name] = parseInt(i, 10);
+        if (count >>= 1)
+            string += string;
     }
-    oop.mixin(ret, ret.MODIFIER_KEYS);
-    oop.mixin(ret, ret.PRINTABLE_KEYS);
-    oop.mixin(ret, ret.FUNCTION_KEYS);
-    ret.enter = ret["return"];
-    ret.escape = ret.esc;
-    ret.del = ret["delete"];
-    ret[173] = '-';
-
-    return ret;
-})();
-oop.mixin(exports, Keys);
-
-exports.keyCodeToString = function(keyCode) {
-    return (Keys[keyCode] || String.fromCharCode(keyCode)).toLowerCase();
-}
+    return result;
+};
 
-});
+var trimBeginRegexp = /^\s\s*/;
+var trimEndRegexp = /\s\s*$/;
 
-define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
+exports.stringTrimLeft = function (string) {
+    return string.replace(trimBeginRegexp, '');
+};
 
+exports.stringTrimRight = function (string) {
+    return string.replace(trimEndRegexp, '');
+};
 
-exports.inherits = (function() {
-    var tempCtor = function() {};
-    return function(ctor, superCtor) {
-        tempCtor.prototype = superCtor.prototype;
-        ctor.super_ = superCtor.prototype;
-        ctor.prototype = new tempCtor();
-        ctor.prototype.constructor = ctor;
-    };
-}());
+exports.copyObject = function(obj) {
+    var copy = {};
+    for (var key in obj) {
+        copy[key] = obj[key];
+    }
+    return copy;
+};
 
-exports.mixin = function(obj, mixin) {
-    for (var key in mixin) {
-        obj[key] = mixin[key];
+exports.copyArray = function(array){
+    var copy = [];
+    for (var i=0, l=array.length; i<l; i++) {
+        if (array[i] && typeof array[i] == "object")
+            copy[i] = this.copyObject( array[i] );
+        else 
+            copy[i] = array[i];
     }
-    return obj;
+    return copy;
 };
 
-exports.implement = function(proto, mixin) {
-    exports.mixin(proto, mixin);
+exports.deepCopy = function (obj) {
+    if (typeof obj !== "object" || !obj)
+        return obj;
+    var cons = obj.constructor;
+    if (cons === RegExp)
+        return obj;
+    
+    var copy = cons();
+    for (var key in obj) {
+        if (typeof obj[key] === "object") {
+            copy[key] = exports.deepCopy(obj[key]);
+        } else {
+            copy[key] = obj[key];
+        }
+    }
+    return copy;
 };
 
-});
+exports.arrayToMap = function(arr) {
+    var map = {};
+    for (var i=0; i<arr.length; i++) {
+        map[arr[i]] = 1;
+    }
+    return map;
 
-define('ace/lib/useragent', ['require', 'exports', 'module' ], function(require, exports, module) {
-exports.OS = {
-    LINUX: "LINUX",
-    MAC: "MAC",
-    WINDOWS: "WINDOWS"
 };
-exports.getOS = function() {
-    if (exports.isMac) {
-        return exports.OS.MAC;
-    } else if (exports.isLinux) {
-        return exports.OS.LINUX;
-    } else {
-        return exports.OS.WINDOWS;
+
+exports.createMap = function(props) {
+    var map = Object.create(null);
+    for (var i in props) {
+        map[i] = props[i];
     }
+    return map;
+};
+exports.arrayRemove = function(array, value) {
+  for (var i = 0; i <= array.length; i++) {
+    if (value === array[i]) {
+      array.splice(i, 1);
+    }
+  }
 };
-if (typeof navigator != "object")
-    return;
 
-var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
-var ua = navigator.userAgent;
-exports.isWin = (os == "win");
-exports.isMac = (os == "mac");
-exports.isLinux = (os == "linux");
-exports.isIE = 
-    (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
-    && parseFloat(navigator.userAgent.match(/MSIE ([0-9]+[\.0-9]+)/)[1]);
-    
-exports.isOldIE = exports.isIE && exports.isIE < 9;
-exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko";
-exports.isOldGecko = exports.isGecko && parseInt((navigator.userAgent.match(/rv\:(\d+)/)||[])[1], 10) < 4;
-exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
-exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
+exports.escapeRegExp = function(str) {
+    return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
+};
 
-exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
+exports.escapeHTML = function(str) {
+    return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
+};
 
-exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
+exports.getMatchOffsets = function(string, regExp) {
+    var matches = [];
 
-exports.isIPad = ua.indexOf("iPad") >= 0;
+    string.replace(regExp, function(str) {
+        matches.push({
+            offset: arguments[arguments.length-2],
+            length: str.length
+        });
+    });
 
-exports.isTouchPad = ua.indexOf("TouchPad") >= 0;
+    return matches;
+};
+exports.deferredCall = function(fcn) {
+    var timer = null;
+    var callback = function() {
+        timer = null;
+        fcn();
+    };
 
-});
+    var deferred = function(timeout) {
+        deferred.cancel();
+        timer = setTimeout(callback, timeout || 0);
+        return deferred;
+    };
 
-define('ace/editor', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/useragent', 'ace/keyboard/textinput', 'ace/mouse/mouse_handler', 'ace/mouse/fold_handler', 'ace/keyboard/keybinding', 'ace/edit_session', 'ace/search', 'ace/range', 'ace/lib/event_emitter', 'ace/commands/command_manager', 'ace/commands/default_commands', 'ace/config'], function(require, exports, module) {
+    deferred.schedule = deferred;
 
+    deferred.call = function() {
+        this.cancel();
+        fcn();
+        return deferred;
+    };
 
-require("./lib/fixoldbrowsers");
+    deferred.cancel = function() {
+        clearTimeout(timer);
+        timer = null;
+        return deferred;
+    };
+    
+    deferred.isPending = function() {
+        return timer;
+    };
 
-var oop = require("./lib/oop");
-var dom = require("./lib/dom");
-var lang = require("./lib/lang");
-var useragent = require("./lib/useragent");
-var TextInput = require("./keyboard/textinput").TextInput;
-var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
-var FoldHandler = require("./mouse/fold_handler").FoldHandler;
-var KeyBinding = require("./keyboard/keybinding").KeyBinding;
-var EditSession = require("./edit_session").EditSession;
-var Search = require("./search").Search;
-var Range = require("./range").Range;
-var EventEmitter = require("./lib/event_emitter").EventEmitter;
-var CommandManager = require("./commands/command_manager").CommandManager;
-var defaultCommands = require("./commands/default_commands").commands;
-var config = require("./config");
-var Editor = function(renderer, session) {
-    var container = renderer.getContainerElement();
-    this.container = container;
-    this.renderer = renderer;
+    return deferred;
+};
 
-    this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
-    this.textInput  = new TextInput(renderer.getTextAreaContainer(), this);
-    this.renderer.textarea = this.textInput.getElement();
-    this.keyBinding = new KeyBinding(this);
-    this.$mouseHandler = new MouseHandler(this);
-    new FoldHandler(this);
 
-    this.$blockScrolling = 0;
-    this.$search = new Search().set({
-        wrap: true
-    });
+exports.delayedCall = function(fcn, defaultTimeout) {
+    var timer = null;
+    var callback = function() {
+        timer = null;
+        fcn();
+    };
 
-    this.$historyTracker = this.$historyTracker.bind(this);
-    this.commands.on("exec", this.$historyTracker);
+    var _self = function(timeout) {
+        if (timer == null)
+            timer = setTimeout(callback, timeout || defaultTimeout);
+    };
 
-    this.$initOperationListeners();
-    
-    this._$emitInputEvent = lang.delayedCall(function() {
-        this._signal("input", {});
-        this.session.bgTokenizer && this.session.bgTokenizer.scheduleStart();
-    }.bind(this));
-    
-    this.on("change", function(_, _self) {
-        _self._$emitInputEvent.schedule(31);
-    });
+    _self.delay = function(timeout) {
+        timer && clearTimeout(timer);
+        timer = setTimeout(callback, timeout || defaultTimeout);
+    };
+    _self.schedule = _self;
 
-    this.setSession(session || new EditSession(""));
-    config.resetOptions(this);
-    config._emit("editor", this);
-};
+    _self.call = function() {
+        this.cancel();
+        fcn();
+    };
 
-(function(){
+    _self.cancel = function() {
+        timer && clearTimeout(timer);
+        timer = null;
+    };
 
-    oop.implement(this, EventEmitter);
+    _self.isPending = function() {
+        return timer;
+    };
 
-    this.$initOperationListeners = function() {
-        function last(a) {return a[a.length - 1]};
+    return _self;
+};
+});
 
-        this.selections = [];
-        this.commands.on("exec", function(e) {
-            this.startOperation(e);
-
-            var command = e.command;
-            if (command.group == "fileJump") {
-                var prev = this.prevOp;
-                if (!prev || prev.command.group != "fileJump") {
-                    this.lastFileJumpPos = last(this.selections)
-                }
-            } else {
-                this.lastFileJumpPos = null;
-            }
-        }.bind(this), true);
+define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang"], function(require, exports, module) {
+"use strict";
 
-        this.commands.on("afterExec", function(e) {
-            var command = e.command;
+var event = require("../lib/event");
+var useragent = require("../lib/useragent");
+var dom = require("../lib/dom");
+var lang = require("../lib/lang");
+var BROKEN_SETDATA = useragent.isChrome < 18;
+var USE_IE_MIME_TYPE =  useragent.isIE;
 
-            if (command.group == "fileJump") {
-                if (this.lastFileJumpPos && !this.curOp.selectionChanged) {
-                    this.selection.fromJSON(this.lastFileJumpPos);
-                    return
-                }
-            }
-            this.endOperation(e);
-        }.bind(this), true);
+var TextInput = function(parentNode, host) {
+    var text = dom.createElement("textarea");
+    text.className = "ace_text-input";
 
-        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));
-
-        this.on("change", function() {
-            this.curOp || this.startOperation();
-            this.curOp.docChanged = true;
-        }.bind(this), true);
+    if (useragent.isTouchPad)
+        text.setAttribute("x-palm-disable-auto-cap", true);
 
-        this.on("changeSelection", function() {
-            this.curOp || this.startOperation();
-            this.curOp.selectionChanged = true;
-        }.bind(this), true);
-    }
+    text.setAttribute("wrap", "off");
+    text.setAttribute("autocorrect", "off");
+    text.setAttribute("autocapitalize", "off");
+    text.setAttribute("spellcheck", false);
 
-    this.curOp = null;
-    this.prevOp = {};
-    this.startOperation = function(commadEvent) {
-        if (this.curOp) {
-            if (!commadEvent || this.curOp.command)
-                return;
-            this.prevOp = this.curOp;
-        }
-        if (!commadEvent) {
-            this.previousCommand = null;
-            commadEvent = {};
-        }
+    text.style.opacity = "0";
+    if (useragent.isOldIE) text.style.top = "-100px";
+    parentNode.insertBefore(text, parentNode.firstChild);
 
-        this.$opResetTimer.schedule();
-        this.curOp = {
-            command: commadEvent.command || {},
-            args: commadEvent.args
-        };
+    var PLACEHOLDER = "\x01\x01";
 
-        this.selections.push(this.selection.toJSON());
+    var copied = false;
+    var pasted = false;
+    var inComposition = false;
+    var tempStyle = '';
+    var isSelectionEmpty = true;
+    try { var isFocused = document.activeElement === text; } catch(e) {}
+    
+    event.addListener(text, "blur", function(e) {
+        host.onBlur(e);
+        isFocused = false;
+    });
+    event.addListener(text, "focus", function(e) {
+        isFocused = true;
+        host.onFocus(e);
+        resetSelection();
+    });
+    this.focus = function() {
+        text.style.position = "fixed";
+        text.style.top = "-10000000px";
+        text.focus();
+        setTimeout(function() {
+            text.style.position = "";
+        }, 0);
+    };
+    this.blur = function() { text.blur(); };
+    this.isFocused = function() {
+        return isFocused;
     };
+    var syncSelection = lang.delayedCall(function() {
+        isFocused && resetSelection(isSelectionEmpty);
+    });
+    var syncValue = lang.delayedCall(function() {
+         if (!inComposition) {
+            text.value = PLACEHOLDER;
+            isFocused && resetSelection();
+         }
+    });
 
-    this.endOperation = function() {
-        if (this.curOp) {
-            this.prevOp = this.curOp;
-            this.curOp = null;
+    function resetSelection(isEmpty) {
+        if (inComposition)
+            return;
+        if (inputHandler) {
+            selectionStart = 0;
+            selectionEnd = isEmpty ? 0 : text.value.length - 1;
+        } else {
+            var selectionStart = isEmpty ? 2 : 1;
+            var selectionEnd = 2;
         }
-    };
+        try {
+            text.setSelectionRange(selectionStart, selectionEnd);
+        } catch(e){}
+    }
 
-    this.$historyTracker = function(e) {
-        if (!this.$mergeUndoDeltas)
+    function resetValue() {
+        if (inComposition)
             return;
+        text.value = PLACEHOLDER;
+        if (useragent.isWebKit)
+            syncValue.schedule();
+    }
 
+    useragent.isWebKit || host.addEventListener('changeSelection', function() {
+        if (host.selection.isEmpty() != isSelectionEmpty) {
+            isSelectionEmpty = !isSelectionEmpty;
+            syncSelection.schedule();
+        }
+    });
 
-        var prev = this.prevOp;
-        var mergeableCommands = ["backspace", "del", "insertstring"];
-        var shouldMerge = prev.command && (e.command.name == prev.command.name);
-        if (e.command.name == "insertstring") {
-            var text = e.args;
-            if (this.mergeNextCommand === undefined)
-                this.mergeNextCommand = true;
+    resetValue();
+    if (isFocused)
+        host.onFocus();
 
-            shouldMerge = shouldMerge
-                && this.mergeNextCommand // previous command allows to coalesce with
-                && (!/\s/.test(text) || /\s/.test(prev.args)) // previous insertion was of same type
 
-            this.mergeNextCommand = true;
-        } else {
-            shouldMerge = shouldMerge
-                && mergeableCommands.indexOf(e.command.name) !== -1// the command is mergeable
+    var isAllSelected = function(text) {
+        return text.selectionStart === 0 && text.selectionEnd === text.value.length;
+    };
+    if (!text.setSelectionRange && text.createTextRange) {
+        text.setSelectionRange = function(selectionStart, selectionEnd) {
+            var range = this.createTextRange();
+            range.collapse(true);
+            range.moveStart('character', selectionStart);
+            range.moveEnd('character', selectionEnd);
+            range.select();
+        };
+        isAllSelected = function(text) {
+            try {
+                var range = text.ownerDocument.selection.createRange();
+            }catch(e) {}
+            if (!range || range.parentElement() != text) return false;
+                return range.text == text.value;
         }
+    }
+    if (useragent.isOldIE) {
+        var inPropertyChange = false;
+        var onPropertyChange = function(e){
+            if (inPropertyChange)
+                return;
+            var data = text.value;
+            if (inComposition || !data || data == PLACEHOLDER)
+                return;
+            if (e && data == PLACEHOLDER[0])
+                return syncProperty.schedule();
 
-        if (
-            this.$mergeUndoDeltas != "always"
-            && Date.now() - this.sequenceStartTime > 2000
-        ) {
-            shouldMerge = false; // the sequence is too long
-        }
+            sendText(data);
+            inPropertyChange = true;
+            resetValue();
+            inPropertyChange = false;
+        };
+        var syncProperty = lang.delayedCall(onPropertyChange);
+        event.addListener(text, "propertychange", onPropertyChange);
 
-        if (shouldMerge)
-            this.session.mergeUndoDeltas = true;
-        else if (mergeableCommands.indexOf(e.command.name) !== -1)
-            this.sequenceStartTime = Date.now();
+        var keytable = { 13:1, 27:1 };
+        event.addListener(text, "keyup", function (e) {
+            if (inComposition && (!text.value || keytable[e.keyCode]))
+                setTimeout(onCompositionEnd, 0);
+            if ((text.value.charCodeAt(0)||0) < 129) {
+                return syncProperty.call();
+            }
+            inComposition ? onCompositionUpdate() : onCompositionStart();
+        });
+        event.addListener(text, "keydown", function (e) {
+            syncProperty.schedule(50);
+        });
+    }
+
+    var onSelect = function(e) {
+        if (copied) {
+            copied = false;
+        } else if (isAllSelected(text)) {
+            host.selectAll();
+            resetSelection();
+        } else if (inputHandler) {
+            resetSelection(host.selection.isEmpty());
+        }
     };
-    this.setKeyboardHandler = function(keyboardHandler) {
-        if (!keyboardHandler) {
-            this.keyBinding.setKeyboardHandler(null);
-        } else if (typeof keyboardHandler == "string") {
-            this.$keybindingId = keyboardHandler;
-            var _self = this;
-            config.loadModule(["keybinding", keyboardHandler], function(module) {
-                if (_self.$keybindingId == keyboardHandler)
-                    _self.keyBinding.setKeyboardHandler(module && module.handler);
-            });
+
+    var inputHandler = null;
+    this.setInputHandler = function(cb) {inputHandler = cb};
+    this.getInputHandler = function() {return inputHandler};
+    var afterContextMenu = false;
+    
+    var sendText = function(data) {
+        if (inputHandler) {
+            data = inputHandler(data);
+            inputHandler = null;
+        }
+        if (pasted) {
+            resetSelection();
+            if (data)
+                host.onPaste(data);
+            pasted = false;
+        } else if (data == PLACEHOLDER.charAt(0)) {
+            if (afterContextMenu)
+                host.execCommand("del", {source: "ace"});
+            else // some versions of android do not fire keydown when pressing backspace
+                host.execCommand("backspace", {source: "ace"});
         } else {
-            this.$keybindingId = null;
-            this.keyBinding.setKeyboardHandler(keyboardHandler);
+            if (data.substring(0, 2) == PLACEHOLDER)
+                data = data.substr(2);
+            else if (data.charAt(0) == PLACEHOLDER.charAt(0))
+                data = data.substr(1);
+            else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
+                data = data.slice(0, -1);
+            if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
+                data = data.slice(0, -1);
+            
+            if (data)
+                host.onTextInput(data);
         }
+        if (afterContextMenu)
+            afterContextMenu = false;
     };
-    this.getKeyboardHandler = function() {
-        return this.keyBinding.getKeyboardHandler();
+    var onInput = function(e) {
+        if (inComposition)
+            return;
+        var data = text.value;
+        sendText(data);
+        resetValue();
     };
-    this.setSession = function(session) {
-        if (this.session == session)
+    
+    var handleClipboardData = function(e, data) {
+        var clipboardData = e.clipboardData || window.clipboardData;
+        if (!clipboardData || BROKEN_SETDATA)
             return;
-
-        if (this.session) {
-            var oldSession = this.session;
-            this.session.removeEventListener("change", this.$onDocumentChange);
-            this.session.removeEventListener("changeMode", this.$onChangeMode);
-            this.session.removeEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
-            this.session.removeEventListener("changeTabSize", this.$onChangeTabSize);
-            this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit);
-            this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode);
-            this.session.removeEventListener("onChangeFold", this.$onChangeFold);
-            this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker);
-            this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker);
-            this.session.removeEventListener("changeBreakpoint", this.$onChangeBreakpoint);
-            this.session.removeEventListener("changeAnnotation", this.$onChangeAnnotation);
-            this.session.removeEventListener("changeOverwrite", this.$onCursorChange);
-            this.session.removeEventListener("changeScrollTop", this.$onScrollTopChange);
-            this.session.removeEventListener("changeScrollLeft", this.$onScrollLeftChange);
-
-            var selection = this.session.getSelection();
-            selection.removeEventListener("changeCursor", this.$onCursorChange);
-            selection.removeEventListener("changeSelection", this.$onSelectionChange);
+        var mime = USE_IE_MIME_TYPE ? "Text" : "text/plain";
+        if (data) {
+            return clipboardData.setData(mime, data) !== false;
+        } else {
+            return clipboardData.getData(mime);
         }
+    };
 
-        this.session = session;
-
-        this.$onDocumentChange = this.onDocumentChange.bind(this);
-        session.addEventListener("change", this.$onDocumentChange);
-        this.renderer.setSession(session);
-
-        this.$onChangeMode = this.onChangeMode.bind(this);
-        session.addEventListener("changeMode", this.$onChangeMode);
-
-        this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
-        session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
-
-        this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
-        session.addEventListener("changeTabSize", this.$onChangeTabSize);
-
-        this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
-        session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit);
-
-        this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
-        session.addEventListener("changeWrapMode", this.$onChangeWrapMode);
-
-        this.$onChangeFold = this.onChangeFold.bind(this);
-        session.addEventListener("changeFold", this.$onChangeFold);
-
-        this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
-        this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker);
+    var doCopy = function(e, isCut) {
+        var data = host.getCopyText();
+        if (!data)
+            return event.preventDefault(e);
 
-        this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
-        this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker);
-
-        this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
-        this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint);
-
-        this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
-        this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation);
-
-        this.$onCursorChange = this.onCursorChange.bind(this);
-        this.session.addEventListener("changeOverwrite", this.$onCursorChange);
-
-        this.$onScrollTopChange = this.onScrollTopChange.bind(this);
-        this.session.addEventListener("changeScrollTop", this.$onScrollTopChange);
-
-        this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
-        this.session.addEventListener("changeScrollLeft", this.$onScrollLeftChange);
-
-        this.selection = session.getSelection();
-        this.selection.addEventListener("changeCursor", this.$onCursorChange);
-
-        this.$onSelectionChange = this.onSelectionChange.bind(this);
-        this.selection.addEventListener("changeSelection", this.$onSelectionChange);
-
-        this.onChangeMode();
-
-        this.$blockScrolling += 1;
-        this.onCursorChange();
-        this.$blockScrolling -= 1;
-
-        this.onScrollTopChange();
-        this.onScrollLeftChange();
-        this.onSelectionChange();
-        this.onChangeFrontMarker();
-        this.onChangeBackMarker();
-        this.onChangeBreakpoint();
-        this.onChangeAnnotation();
-        this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
-        this.renderer.updateFull();
-
-        this._emit("changeSession", {
-            session: session,
-            oldSession: oldSession
-        });
-    };
-    this.getSession = function() {
-        return this.session;
-    };
-    this.setValue = function(val, cursorPos) {
-        this.session.doc.setValue(val);
-
-        if (!cursorPos)
-            this.selectAll();
-        else if (cursorPos == 1)
-            this.navigateFileEnd();
-        else if (cursorPos == -1)
-            this.navigateFileStart();
-
-        return val;
-    };
-    this.getValue = function() {
-        return this.session.getValue();
-    };
-    this.getSelection = function() {
-        return this.selection;
-    };
-    this.resize = function(force) {
-        this.renderer.onResize(force);
-    };
-    this.setTheme = function(theme) {
-        this.renderer.setTheme(theme);
-    };
-    this.getTheme = function() {
-        return this.renderer.getTheme();
-    };
-    this.setStyle = function(style) {
-        this.renderer.setStyle(style);
+        if (handleClipboardData(e, data)) {
+            isCut ? host.onCut() : host.onCopy();
+            event.preventDefault(e);
+        } else {
+            copied = true;
+            text.value = data;
+            text.select();
+            setTimeout(function(){
+                copied = false;
+                resetValue();
+                resetSelection();
+                isCut ? host.onCut() : host.onCopy();
+            });
+        }
     };
-    this.unsetStyle = function(style) {
-        this.renderer.unsetStyle(style);
+    
+    var onCut = function(e) {
+        doCopy(e, true);
     };
-    this.getFontSize = function () {
-        return this.getOption("fontSize") ||
-           dom.computedStyle(this.container, "fontSize");
+    
+    var onCopy = function(e) {
+        doCopy(e, false);
     };
-    this.setFontSize = function(size) {
-        this.setOption("fontSize", size);
+    
+    var onPaste = function(e) {
+        var data = handleClipboardData(e);
+        if (typeof data == "string") {
+            if (data)
+                host.onPaste(data);
+            if (useragent.isIE)
+                setTimeout(resetSelection);
+            event.preventDefault(e);
+        }
+        else {
+            text.value = "";
+            pasted = true;
+        }
     };
 
-    this.$highlightBrackets = function() {
-        if (this.session.$bracketHighlight) {
-            this.session.removeMarker(this.session.$bracketHighlight);
-            this.session.$bracketHighlight = null;
-        }
+    event.addCommandKeyListener(text, host.onCommandKey.bind(host));
 
-        if (this.$highlightPending) {
-            return;
-        }
-        var self = this;
-        this.$highlightPending = true;
-        setTimeout(function() {
-            self.$highlightPending = false;
+    event.addListener(text, "select", onSelect);
 
-            var pos = self.session.findMatchingBracket(self.getCursorPosition());
-            if (pos) {
-                var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
-            } else if (self.session.$mode.getMatching) {
-                var range = self.session.$mode.getMatching(self.session);
+    event.addListener(text, "input", onInput);
+
+    event.addListener(text, "cut", onCut);
+    event.addListener(text, "copy", onCopy);
+    event.addListener(text, "paste", onPaste);
+    if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)){
+        event.addListener(parentNode, "keydown", function(e) {
+            if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
+                return;
+
+            switch (e.keyCode) {
+                case 67:
+                    onCopy(e);
+                    break;
+                case 86:
+                    onPaste(e);
+                    break;
+                case 88:
+                    onCut(e);
+                    break;
             }
-            if (range)
-                self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text");
-        }, 50);
-    };
-    this.focus = function() {
-        var _self = this;
-        setTimeout(function() {
-            _self.textInput.focus();
         });
-        this.textInput.focus();
-    };
-    this.isFocused = function() {
-        return this.textInput.isFocused();
-    };
-    this.blur = function() {
-        this.textInput.blur();
-    };
-    this.onFocus = function() {
-        if (this.$isFocused)
-            return;
-        this.$isFocused = true;
-        this.renderer.showCursor();
-        this.renderer.visualizeFocus();
-        this._emit("focus");
-    };
-    this.onBlur = function() {
-        if (!this.$isFocused)
+    }
+    var onCompositionStart = function(e) {
+        if (inComposition || !host.onCompositionStart || host.$readOnly) 
             return;
-        this.$isFocused = false;
-        this.renderer.hideCursor();
-        this.renderer.visualizeBlur();
-        this._emit("blur");
+        inComposition = {};
+        host.onCompositionStart();
+        setTimeout(onCompositionUpdate, 0);
+        host.on("mousedown", onCompositionEnd);
+        if (!host.selection.isEmpty()) {
+            host.insert("");
+            host.session.markUndoGroup();
+            host.selection.clearSelection();
+        }
+        host.session.markUndoGroup();
     };
 
-    this.$cursorChange = function() {
-        this.renderer.updateCursor();
+    var onCompositionUpdate = function() {
+        if (!inComposition || !host.onCompositionUpdate || host.$readOnly)
+            return;
+        var val = text.value.replace(/\x01/g, "");
+        if (inComposition.lastValue === val) return;
+        
+        host.onCompositionUpdate(val);
+        if (inComposition.lastValue)
+            host.undo();
+        inComposition.lastValue = val;
+        if (inComposition.lastValue) {
+            var r = host.selection.getRange();
+            host.insert(inComposition.lastValue);
+            host.session.markUndoGroup();
+            inComposition.range = host.selection.getRange();
+            host.selection.setRange(r);
+            host.selection.clearSelection();
+        }
     };
-    this.onDocumentChange = function(e) {
-        var delta = e.data;
-        var range = delta.range;
-        var lastRow;
-
-        if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines")
-            lastRow = range.end.row;
-        else
-            lastRow = Infinity;
-        this.renderer.updateLines(range.start.row, lastRow);
 
-        this._emit("change", e);
-        this.$cursorChange();
+    var onCompositionEnd = function(e) {
+        if (!host.onCompositionEnd || host.$readOnly) return;
+        var c = inComposition;
+        inComposition = false;
+        var timer = setTimeout(function() {
+            timer = null;
+            var str = text.value.replace(/\x01/g, "");
+            if (inComposition)
+                return;
+            else if (str == c.lastValue)
+                resetValue();
+            else if (!c.lastValue && str) {
+                resetValue();
+                sendText(str);
+            }
+        });
+        inputHandler = function compositionInputHandler(str) {
+            if (timer)
+                clearTimeout(timer);
+            str = str.replace(/\x01/g, "");
+            if (str == c.lastValue)
+                return "";
+            if (c.lastValue && timer)
+                host.undo();
+            return str;
+        };
+        host.onCompositionEnd();
+        host.removeListener("mousedown", onCompositionEnd);
+        if (e.type == "compositionend" && c.range) {
+            host.selection.setRange(c.range);
+        }
     };
+    
+    
 
-    this.onTokenizerUpdate = function(e) {
-        var rows = e.data;
-        this.renderer.updateLines(rows.first, rows.last);
-    };
+    var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
 
+    event.addListener(text, "compositionstart", onCompositionStart);
+    if (useragent.isGecko) {
+        event.addListener(text, "text", function(){syncComposition.schedule()});
+    } else {
+        event.addListener(text, "keyup", function(){syncComposition.schedule()});
+        event.addListener(text, "keydown", function(){syncComposition.schedule()});
+    }
+    event.addListener(text, "compositionend", onCompositionEnd);
 
-    this.onScrollTopChange = function() {
-        this.renderer.scrollToY(this.session.getScrollTop());
+    this.getElement = function() {
+        return text;
     };
 
-    this.onScrollLeftChange = function() {
-        this.renderer.scrollToX(this.session.getScrollLeft());
+    this.setReadOnly = function(readOnly) {
+       text.readOnly = readOnly;
     };
-    this.onCursorChange = function() {
-        this.$cursorChange();
 
-        if (!this.$blockScrolling) {
-            this.renderer.scrollCursorIntoView();
-        }
-
-        this.$highlightBrackets();
-        this.$updateHighlightActiveLine();
-        this._emit("changeSelection");
+    this.onContextMenu = function(e) {
+        afterContextMenu = true;
+        resetSelection(host.selection.isEmpty());
+        host._emit("nativecontextmenu", {target: host, domEvent: e});
+        this.moveToMouse(e, true);
     };
+    
+    this.moveToMouse = function(e, bringToFront) {
+        if (!bringToFront && useragent.isOldIE)
+            return;
+        if (!tempStyle)
+            tempStyle = text.style.cssText;
+        text.style.cssText = (bringToFront ? "z-index:100000;" : "")
+            + "height:" + text.style.height + ";"
+            + (useragent.isIE ? "opacity:0.1;" : "");
 
-    this.$updateHighlightActiveLine = function() {
-        var session = this.getSession();
+        var rect = host.container.getBoundingClientRect();
+        var style = dom.computedStyle(host.container);
+        var top = rect.top + (parseInt(style.borderTopWidth) || 0);
+        var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
+        var maxTop = rect.bottom - top - text.clientHeight -2;
+        var move = function(e) {
+            text.style.left = e.clientX - left - 2 + "px";
+            text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
+        }; 
+        move(e);
 
-        var highlight;
-        if (this.$highlightActiveLine) {
-            if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
-                highlight = this.getCursorPosition();
-            if (this.renderer.$maxLines && this.session.getLength() === 1)
-                highlight = false;
-        }
+        if (e.type != "mousedown")
+            return;
 
-        if (session.$highlightLineMarker && !highlight) {
-            session.removeMarker(session.$highlightLineMarker.id);
-            session.$highlightLineMarker = null;
-        } else if (!session.$highlightLineMarker && highlight) {
-            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
-            range.id = session.addMarker(range, "ace_active-line", "screenLine");
-            session.$highlightLineMarker = range;
-        } else if (highlight) {
-            session.$highlightLineMarker.start.row = highlight.row;
-            session.$highlightLineMarker.end.row = highlight.row;
-            session.$highlightLineMarker.start.column = highlight.column;
-            session._emit("changeBackMarker");
-        }
+        if (host.renderer.$keepTextAreaAtCursor)
+            host.renderer.$keepTextAreaAtCursor = null;
+        if (useragent.isWin && !useragent.isOldIE)
+            event.capture(host.container, move, onContextMenuClose);
     };
 
-    this.onSelectionChange = function(e) {
-        var session = this.session;
+    this.onContextMenuClose = onContextMenuClose;
+    var closeTimeout;
+    function onContextMenuClose() {
+        clearTimeout(closeTimeout)
+        closeTimeout = setTimeout(function () {
+            if (tempStyle) {
+                text.style.cssText = tempStyle;
+                tempStyle = '';
+            }
+            if (host.renderer.$keepTextAreaAtCursor == null) {
+                host.renderer.$keepTextAreaAtCursor = true;
+                host.renderer.$moveTextAreaToCursor();
+            }
+        }, useragent.isOldIE ? 200 : 0);
+    }
 
-        if (session.$selectionMarker) {
-            session.removeMarker(session.$selectionMarker);
-        }
-        session.$selectionMarker = null;
+    var onContextMenu = function(e) {
+        host.textInput.onContextMenu(e);
+        onContextMenuClose();
+    };
+    event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
+    event.addListener(text, "contextmenu", onContextMenu);
+};
 
-        if (!this.selection.isEmpty()) {
-            var range = this.selection.getRange();
-            var style = this.getSelectionStyle();
-            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
-        } else {
-            this.$updateHighlightActiveLine();
-        }
+exports.TextInput = TextInput;
+});
 
-        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
-        this.session.highlight(re);
+define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
+"use strict";
 
-        this._emit("changeSelection");
-    };
+var dom = require("../lib/dom");
+var event = require("../lib/event");
+var useragent = require("../lib/useragent");
 
-    this.$getSelectionHighLightRegexp = function() {
-        var session = this.session;
+var DRAG_OFFSET = 0; // pixels
 
-        var selection = this.getSelectionRange();
-        if (selection.isEmpty() || selection.isMultiLine())
-            return;
+function DefaultHandlers(mouseHandler) {
+    mouseHandler.$clickSelection = null;
 
-        var startOuter = selection.start.column - 1;
-        var endOuter = selection.end.column + 1;
-        var line = session.getLine(selection.start.row);
-        var lineCols = line.length;
-        var needle = line.substring(Math.max(startOuter, 0),
-                                    Math.min(endOuter, lineCols));
-        if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
-            (endOuter <= lineCols && /[\w\d]$/.test(needle)))
-            return;
+    var editor = mouseHandler.editor;
+    editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
+    editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
+    editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
+    editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
+    editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler));
 
-        needle = line.substring(selection.start.column, selection.end.column);
-        if (!/^[\w\d]+$/.test(needle))
-            return;
+    var exports = ["select", "startSelect", "selectEnd", "selectAllEnd", "selectByWordsEnd",
+        "selectByLinesEnd", "dragWait", "dragWaitEnd", "focusWait"];
 
-        var re = this.$search.$assembleRegExp({
-            wholeWord: true,
-            caseSensitive: true,
-            needle: needle
-        });
+    exports.forEach(function(x) {
+        mouseHandler[x] = this[x];
+    }, this);
 
-        return re;
-    };
+    mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
+    mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
+}
 
+(function() {
 
-    this.onChangeFrontMarker = function() {
-        this.renderer.updateFrontMarkers();
-    };
+    this.onMouseDown = function(ev) {
+        var inSelection = ev.inSelection();
+        var pos = ev.getDocumentPosition();
+        this.mousedownEvent = ev;
+        var editor = this.editor;
 
-    this.onChangeBackMarker = function() {
-        this.renderer.updateBackMarkers();
-    };
+        var button = ev.getButton();
+        if (button !== 0) {
+            var selectionRange = editor.getSelectionRange();
+            var selectionEmpty = selectionRange.isEmpty();
+            editor.$blockScrolling++;
+            if (selectionEmpty)
+                editor.selection.moveToPosition(pos);
+            editor.$blockScrolling--;
+            editor.textInput.onContextMenu(ev.domEvent);
+            return; // stopping event here breaks contextmenu on ff mac
+        }
 
+        this.mousedownEvent.time = Date.now();
+        if (inSelection && !editor.isFocused()) {
+            editor.focus();
+            if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
+                this.setState("focusWait");
+                this.captureMouse(ev);
+                return;
+            }
+        }
 
-    this.onChangeBreakpoint = function() {
-        this.renderer.updateBreakpoints();
+        this.captureMouse(ev);
+        this.startSelect(pos, ev.domEvent._clicks > 1);
+        return ev.preventDefault();
     };
 
-    this.onChangeAnnotation = function() {
-        this.renderer.setAnnotations(this.session.getAnnotations());
+    this.startSelect = function(pos, waitForClickSelection) {
+        pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
+        var editor = this.editor;
+        editor.$blockScrolling++;
+        if (this.mousedownEvent.getShiftKey())
+            editor.selection.selectToPosition(pos);
+        else if (!waitForClickSelection)
+            editor.selection.moveToPosition(pos);
+        if (!waitForClickSelection)
+            this.select();
+        if (editor.renderer.scroller.setCapture) {
+            editor.renderer.scroller.setCapture();
+        }
+        editor.setStyle("ace_selecting");
+        this.setState("select");
+        editor.$blockScrolling--;
     };
 
+    this.select = function() {
+        var anchor, editor = this.editor;
+        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
+        editor.$blockScrolling++;
+        if (this.$clickSelection) {
+            var cmp = this.$clickSelection.comparePoint(cursor);
 
-    this.onChangeMode = function(e) {
-        this.renderer.updateText();
-        this._emit("changeMode", e);
+            if (cmp == -1) {
+                anchor = this.$clickSelection.end;
+            } else if (cmp == 1) {
+                anchor = this.$clickSelection.start;
+            } else {
+                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
+                cursor = orientedRange.cursor;
+                anchor = orientedRange.anchor;
+            }
+            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
+        }
+        editor.selection.selectToPosition(cursor);
+        editor.$blockScrolling--;
+        editor.renderer.scrollCursorIntoView();
     };
 
+    this.extendSelectionBy = function(unitName) {
+        var anchor, editor = this.editor;
+        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
+        var range = editor.selection[unitName](cursor.row, cursor.column);
+        editor.$blockScrolling++;
+        if (this.$clickSelection) {
+            var cmpStart = this.$clickSelection.comparePoint(range.start);
+            var cmpEnd = this.$clickSelection.comparePoint(range.end);
 
-    this.onChangeWrapLimit = function() {
-        this.renderer.updateFull();
+            if (cmpStart == -1 && cmpEnd <= 0) {
+                anchor = this.$clickSelection.end;
+                if (range.end.row != cursor.row || range.end.column != cursor.column)
+                    cursor = range.start;
+            } else if (cmpEnd == 1 && cmpStart >= 0) {
+                anchor = this.$clickSelection.start;
+                if (range.start.row != cursor.row || range.start.column != cursor.column)
+                    cursor = range.end;
+            } else if (cmpStart == -1 && cmpEnd == 1) {
+                cursor = range.end;
+                anchor = range.start;
+            } else {
+                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
+                cursor = orientedRange.cursor;
+                anchor = orientedRange.anchor;
+            }
+            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
+        }
+        editor.selection.selectToPosition(cursor);
+        editor.$blockScrolling--;
+        editor.renderer.scrollCursorIntoView();
     };
 
-    this.onChangeWrapMode = function() {
-        this.renderer.onResize(true);
+    this.selectEnd =
+    this.selectAllEnd =
+    this.selectByWordsEnd =
+    this.selectByLinesEnd = function() {
+        this.$clickSelection = null;
+        this.editor.unsetStyle("ace_selecting");
+        if (this.editor.renderer.scroller.releaseCapture) {
+            this.editor.renderer.scroller.releaseCapture();
+        }
     };
 
+    this.focusWait = function() {
+        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
+        var time = Date.now();
 
-    this.onChangeFold = function() {
-        this.$updateHighlightActiveLine();
-        this.renderer.updateFull();
-    };
-    this.getSelectedText = function() {
-        return this.session.getTextRange(this.getSelectionRange());
-    };
-    this.getCopyText = function() {
-        var text = this.getSelectedText();
-        this._signal("copy", text);
-        return text;
-    };
-    this.onCopy = function() {
-        this.commands.exec("copy", this);
-    };
-    this.onCut = function() {
-        this.commands.exec("cut", this);
-    };
-    this.onPaste = function(text) {
-        if (this.$readOnly)
-            return;
-        this._emit("paste", text);
-        this.insert(text);
+        if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
+            this.startSelect(this.mousedownEvent.getDocumentPosition());
     };
 
+    this.onDoubleClick = function(ev) {
+        var pos = ev.getDocumentPosition();
+        var editor = this.editor;
+        var session = editor.session;
 
-    this.execCommand = function(command, args) {
-        this.commands.exec(command, this, args);
+        var range = session.getBracketRange(pos);
+        if (range) {
+            if (range.isEmpty()) {
+                range.start.column--;
+                range.end.column++;
+            }
+            this.setState("select");
+        } else {
+            range = editor.selection.getWordRange(pos.row, pos.column);
+            this.setState("selectByWords");
+        }
+        this.$clickSelection = range;
+        this.select();
     };
-    this.insert = function(text) {
-        var session = this.session;
-        var mode = session.getMode();
-        var cursor = this.getCursorPosition();
 
-        if (this.getBehavioursEnabled()) {
-            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
-            if (transform) {
-                if (text !== transform.text) {
-                    this.session.mergeUndoDeltas = false;
-                    this.$mergeNextCommand = false;
-                }
-                text = transform.text;
+    this.onTripleClick = function(ev) {
+        var pos = ev.getDocumentPosition();
+        var editor = this.editor;
 
-            }
-        }
-        
-        if (text == "\t")
-            text = this.session.getTabString();
-        if (!this.selection.isEmpty()) {
-            var range = this.getSelectionRange();
-            cursor = this.session.remove(range);
-            this.clearSelection();
-        }
-        else if (this.session.getOverwrite()) {
-            var range = new Range.fromPoints(cursor, cursor);
-            range.end.column += text.length;
-            this.session.remove(range);
+        this.setState("selectByLines");
+        var range = editor.getSelectionRange();
+        if (range.isMultiLine() && range.contains(pos.row, pos.column)) {
+            this.$clickSelection = editor.selection.getLineRange(range.start.row);
+            this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;
+        } else {
+            this.$clickSelection = editor.selection.getLineRange(pos.row);
         }
+        this.select();
+    };
 
-        if (text == "\n" || text == "\r\n") {
-            var line = session.getLine(cursor.row)
-            if (cursor.column > line.search(/\S|$/)) {
-                var d = line.substr(cursor.column).search(/\S|$/);
-                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
-            }
-        }
-        this.clearSelection();
+    this.onQuadClick = function(ev) {
+        var editor = this.editor;
 
-        var start = cursor.column;
-        var lineState = session.getState(cursor.row);
-        var line = session.getLine(cursor.row);
-        var shouldOutdent = mode.checkOutdent(lineState, line, text);
-        var end = session.insert(cursor, text);
+        editor.selectAll();
+        this.$clickSelection = editor.getSelectionRange();
+        this.setState("selectAll");
+    };
 
-        if (transform && transform.selection) {
-            if (transform.selection.length == 2) { // Transform relative to the current column
-                this.selection.setSelectionRange(
-                    new Range(cursor.row, start + transform.selection[0],
-                              cursor.row, start + transform.selection[1]));
-            } else { // Transform relative to the current row.
-                this.selection.setSelectionRange(
-                    new Range(cursor.row + transform.selection[0],
-                              transform.selection[1],
-                              cursor.row + transform.selection[2],
-                              transform.selection[3]));
-            }
+    this.onMouseWheel = function(ev) {
+        if (ev.getAccelKey())
+            return;
+        if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {
+            ev.wheelX = ev.wheelY;
+            ev.wheelY = 0;
         }
 
-        if (session.getDocument().isNewLine(text)) {
-            var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
-
-            session.insert({row: cursor.row+1, column: 0}, lineIndent);
+        var t = ev.domEvent.timeStamp;
+        var dt = t - (this.$lastScrollTime||0);
+        
+        var editor = this.editor;
+        var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
+        if (isScrolable || dt < 200) {
+            this.$lastScrollTime = t;
+            editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
+            return ev.stop();
         }
-        if (shouldOutdent)
-            mode.autoOutdent(lineState, session, cursor.row);
     };
 
-    this.onTextInput = function(text) {
-        this.keyBinding.onTextInput(text);
-    };
+}).call(DefaultHandlers.prototype);
 
-    this.onCommandKey = function(e, hashId, keyCode) {
-        this.keyBinding.onCommandKey(e, hashId, keyCode);
-    };
-    this.setOverwrite = function(overwrite) {
-        this.session.setOverwrite(overwrite);
-    };
-    this.getOverwrite = function() {
-        return this.session.getOverwrite();
-    };
-    this.toggleOverwrite = function() {
-        this.session.toggleOverwrite();
-    };
-    this.setScrollSpeed = function(speed) {
-        this.setOption("scrollSpeed", speed);
-    };
-    this.getScrollSpeed = function() {
-        return this.getOption("scrollSpeed");
-    };
-    this.setDragDelay = function(dragDelay) {
-        this.setOption("dragDelay", dragDelay);
-    };
-    this.getDragDelay = function() {
-        return this.getOption("dragDelay");
-    };
-    this.setSelectionStyle = function(val) {
-        this.setOption("selectionStyle", val);
-    };
-    this.getSelectionStyle = function() {
-        return this.getOption("selectionStyle");
-    };
-    this.setHighlightActiveLine = function(shouldHighlight) {
-        this.setOption("highlightActiveLine", shouldHighlight);
-    };
-    this.getHighlightActiveLine = function() {
-        return this.getOption("highlightActiveLine");
-    };
-    this.setHighlightGutterLine = function(shouldHighlight) {
-        this.setOption("highlightGutterLine", shouldHighlight);
-    };
+exports.DefaultHandlers = DefaultHandlers;
 
-    this.getHighlightGutterLine = function() {
-        return this.getOption("highlightGutterLine");
-    };
-    this.setHighlightSelectedWord = function(shouldHighlight) {
-        this.setOption("highlightSelectedWord", shouldHighlight);
-    };
-    this.getHighlightSelectedWord = function() {
-        return this.$highlightSelectedWord;
-    };
+function calcDistance(ax, ay, bx, by) {
+    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
+}
 
-    this.setAnimatedScroll = function(shouldAnimate){
-        this.renderer.setAnimatedScroll(shouldAnimate);
-    };
+function calcRangeOrientation(range, cursor) {
+    if (range.start.row == range.end.row)
+        var cmp = 2 * cursor.column - range.start.column - range.end.column;
+    else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column)
+        var cmp = cursor.column - 4;
+    else
+        var cmp = 2 * cursor.row - range.start.row - range.end.row;
 
-    this.getAnimatedScroll = function(){
-        return this.renderer.getAnimatedScroll();
-    };
-    this.setShowInvisibles = function(showInvisibles) {
-        this.renderer.setShowInvisibles(showInvisibles);
-    };
-    this.getShowInvisibles = function() {
-        return this.renderer.getShowInvisibles();
-    };
+    if (cmp < 0)
+        return {cursor: range.start, anchor: range.end};
+    else
+        return {cursor: range.end, anchor: range.start};
+}
 
-    this.setDisplayIndentGuides = function(display) {
-        this.renderer.setDisplayIndentGuides(display);
-    };
+});
 
-    this.getDisplayIndentGuides = function() {
-        return this.renderer.getDisplayIndentGuides();
-    };
-    this.setShowPrintMargin = function(showPrintMargin) {
-        this.renderer.setShowPrintMargin(showPrintMargin);
+define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"], function(require, exports, module) {
+"use strict";
+
+var oop = require("./lib/oop");
+var dom = require("./lib/dom");
+function Tooltip (parentNode) {
+    this.isOpen = false;
+    this.$element = null;
+    this.$parentNode = parentNode;
+}
+
+(function() {
+    this.$init = function() {
+        this.$element = dom.createElement("div");
+        this.$element.className = "ace_tooltip";
+        this.$element.style.display = "none";
+        this.$parentNode.appendChild(this.$element);
+        return this.$element;
     };
-    this.getShowPrintMargin = function() {
-        return this.renderer.getShowPrintMargin();
+    this.getElement = function() {
+        return this.$element || this.$init();
     };
-    this.setPrintMarginColumn = function(showPrintMargin) {
-        this.renderer.setPrintMarginColumn(showPrintMargin);
+    this.setText = function(text) {
+        dom.setInnerText(this.getElement(), text);
     };
-    this.getPrintMarginColumn = function() {
-        return this.renderer.getPrintMarginColumn();
+    this.setHtml = function(html) {
+        this.getElement().innerHTML = html;
     };
-    this.setReadOnly = function(readOnly) {
-        this.setOption("readOnly", readOnly);
+    this.setPosition = function(x, y) {
+        this.getElement().style.left = x + "px";
+        this.getElement().style.top = y + "px";
     };
-    this.getReadOnly = function() {
-        return this.getOption("readOnly");
+    this.setClassName = function(className) {
+        dom.addCssClass(this.getElement(), className);
     };
-    this.setBehavioursEnabled = function (enabled) {
-        this.setOption("behavioursEnabled", enabled);
+    this.show = function(text, x, y) {
+        if (text != null)
+            this.setText(text);
+        if (x != null && y != null)
+            this.setPosition(x, y);
+        if (!this.isOpen) {
+            this.getElement().style.display = "block";
+            this.isOpen = true;
+        }
     };
-    this.getBehavioursEnabled = function () {
-        return this.getOption("behavioursEnabled");
+
+    this.hide = function() {
+        if (this.isOpen) {
+            this.getElement().style.display = "none";
+            this.isOpen = false;
+        }
     };
-    this.setWrapBehavioursEnabled = function (enabled) {
-        this.setOption("wrapBehavioursEnabled", enabled);
+    this.getHeight = function() {
+        return this.getElement().offsetHeight;
     };
-    this.getWrapBehavioursEnabled = function () {
-        return this.getOption("wrapBehavioursEnabled");
+    this.getWidth = function() {
+        return this.getElement().offsetWidth;
     };
-    this.setShowFoldWidgets = function(show) {
-        this.setOption("showFoldWidgets", show);
 
-    };
-    this.getShowFoldWidgets = function() {
-        return this.getOption("showFoldWidgets");
-    };
+}).call(Tooltip.prototype);
 
-    this.setFadeFoldWidgets = function(fade) {
-        this.setOption("fadeFoldWidgets", fade);
-    };
+exports.Tooltip = Tooltip;
+});
 
-    this.getFadeFoldWidgets = function() {
-        return this.getOption("fadeFoldWidgets");
-    };
-    this.remove = function(dir) {
-        if (this.selection.isEmpty()){
-            if (dir == "left")
-                this.selection.selectLeft();
-            else
-                this.selection.selectRight();
-        }
+define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"], function(require, exports, module) {
+"use strict";
+var dom = require("../lib/dom");
+var oop = require("../lib/oop");
+var event = require("../lib/event");
+var Tooltip = require("../tooltip").Tooltip;
 
-        var range = this.getSelectionRange();
-        if (this.getBehavioursEnabled()) {
-            var session = this.session;
-            var state = session.getState(range.start.row);
-            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
+function GutterHandler(mouseHandler) {
+    var editor = mouseHandler.editor;
+    var gutter = editor.renderer.$gutterLayer;
+    var tooltip = new GutterTooltip(editor.container);
 
-            if (range.end.column == 0) {
-                var text = session.getTextRange(range);
-                if (text[text.length - 1] == "\n") {
-                    var line = session.getLine(range.end.row)
-                    if (/^\s+$/.test(line)) {
-                        range.end.column = line.length
-                    }
-                }
+    mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
+        if (!editor.isFocused() || e.getButton() != 0)
+            return;
+        var gutterRegion = gutter.getRegion(e);
+
+        if (gutterRegion == "foldWidgets")
+            return;
+
+        var row = e.getDocumentPosition().row;
+        var selection = editor.session.selection;
+
+        if (e.getShiftKey())
+            selection.selectTo(row, 0);
+        else {
+            if (e.domEvent.detail == 2) {
+                editor.selectAll();
+                return e.preventDefault();
             }
-            if (new_range)
-                range = new_range;
+            mouseHandler.$clickSelection = editor.selection.getLineRange(row);
         }
+        mouseHandler.setState("selectByLines");
+        mouseHandler.captureMouse(e);
+        return e.preventDefault();
+    });
 
-        this.session.remove(range);
-        this.clearSelection();
-    };
-    this.removeWordRight = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectWordRight();
 
-        this.session.remove(this.getSelectionRange());
-        this.clearSelection();
-    };
-    this.removeWordLeft = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectWordLeft();
-
-        this.session.remove(this.getSelectionRange());
-        this.clearSelection();
-    };
-    this.removeToLineStart = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectLineStart();
-
-        this.session.remove(this.getSelectionRange());
-        this.clearSelection();
-    };
-    this.removeToLineEnd = function() {
-        if (this.selection.isEmpty())
-            this.selection.selectLineEnd();
+    var tooltipTimeout, mouseEvent, tooltipAnnotation;
 
-        var range = this.getSelectionRange();
-        if (range.start.column == range.end.column && range.start.row == range.end.row) {
-            range.end.column = 0;
-            range.end.row++;
-        }
+    function showTooltip() {
+        var row = mouseEvent.getDocumentPosition().row;
+        var annotation = gutter.$annotations[row];
+        if (!annotation)
+            return hideTooltip();
 
-        this.session.remove(range);
-        this.clearSelection();
-    };
-    this.splitLine = function() {
-        if (!this.selection.isEmpty()) {
-            this.session.remove(this.getSelectionRange());
-            this.clearSelection();
+        var maxRow = editor.session.getLength();
+        if (row == maxRow) {
+            var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;
+            var pos = mouseEvent.$pos;
+            if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))
+                return hideTooltip();
         }
 
-        var cursor = this.getCursorPosition();
-        this.insert("\n");
-        this.moveCursorToPosition(cursor);
-    };
-    this.transposeLetters = function() {
-        if (!this.selection.isEmpty()) {
+        if (tooltipAnnotation == annotation)
             return;
-        }
+        tooltipAnnotation = annotation.text.join("<br/>");
 
-        var cursor = this.getCursorPosition();
-        var column = cursor.column;
-        if (column === 0)
-            return;
+        tooltip.setHtml(tooltipAnnotation);
+        tooltip.show();
+        editor.on("mousewheel", hideTooltip);
 
-        var line = this.session.getLine(cursor.row);
-        var swap, range;
-        if (column < line.length) {
-            swap = line.charAt(column) + line.charAt(column-1);
-            range = new Range(cursor.row, column-1, cursor.row, column+1);
-        }
-        else {
-            swap = line.charAt(column-1) + line.charAt(column-2);
-            range = new Range(cursor.row, column-2, cursor.row, column);
-        }
-        this.session.replace(range, swap);
-    };
-    this.toLowerCase = function() {
-        var originalRange = this.getSelectionRange();
-        if (this.selection.isEmpty()) {
-            this.selection.selectWord();
+        if (mouseHandler.$tooltipFollowsMouse) {
+            moveTooltip(mouseEvent);
+        } else {
+            var gutterElement = gutter.$cells[editor.session.documentToScreenRow(row, 0)].element;
+            var rect = gutterElement.getBoundingClientRect();
+            var style = tooltip.getElement().style;
+            style.left = rect.right + "px";
+            style.top = rect.bottom + "px";
         }
+    }
 
-        var range = this.getSelectionRange();
-        var text = this.session.getTextRange(range);
-        this.session.replace(range, text.toLowerCase());
-        this.selection.setSelectionRange(originalRange);
-    };
-    this.toUpperCase = function() {
-        var originalRange = this.getSelectionRange();
-        if (this.selection.isEmpty()) {
-            this.selection.selectWord();
+    function hideTooltip() {
+        if (tooltipTimeout)
+            tooltipTimeout = clearTimeout(tooltipTimeout);
+        if (tooltipAnnotation) {
+            tooltip.hide();
+            tooltipAnnotation = null;
+            editor.removeEventListener("mousewheel", hideTooltip);
         }
+    }
 
-        var range = this.getSelectionRange();
-        var text = this.session.getTextRange(range);
-        this.session.replace(range, text.toUpperCase());
-        this.selection.setSelectionRange(originalRange);
-    };
-    this.indent = function() {
-        var session = this.session;
-        var range = this.getSelectionRange();
+    function moveTooltip(e) {
+        tooltip.setPosition(e.x, e.y);
+    }
 
-        if (range.start.row < range.end.row) {
-            var rows = this.$getSelectedRows();
-            session.indentRows(rows.first, rows.last, "\t");
-            return;
-        } else if (range.start.column < range.end.column) {
-            var text = session.getTextRange(range)
-            if (!/^\s+$/.test(text)) {
-                var rows = this.$getSelectedRows();
-                session.indentRows(rows.first, rows.last, "\t");
-                return;
-            }
-        }
-        
-        var line = session.getLine(range.start.row)
-        var position = range.start;
-        var size = session.getTabSize();
-        var column = session.documentToScreenColumn(position.row, position.column);
+    mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) {
+        var target = e.domEvent.target || e.domEvent.srcElement;
+        if (dom.hasCssClass(target, "ace_fold-widget"))
+            return hideTooltip();
 
-        if (this.session.getUseSoftTabs()) {
-            var count = (size - column % size);
-            var indentString = lang.stringRepeat(" ", count);
-        } else {
-            var count = column % size;
-            while (line[range.start.column] == " " && count) {
-                range.start.column--;
-                count--;
-            }
-            this.selection.setSelectionRange(range);
-            indentString = "\t";
-        }
-        return this.insert(indentString);
-    };
-    this.blockIndent = function() {
-        var rows = this.$getSelectedRows();
-        this.session.indentRows(rows.first, rows.last, "\t");
-    };
-    this.blockOutdent = function() {
-        var selection = this.session.getSelection();
-        this.session.outdentRows(selection.getRange());
-    };
-    this.sortLines = function() {
-        var rows = this.$getSelectedRows();
-        var session = this.session;
+        if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse)
+            moveTooltip(e);
 
-        var lines = [];
-        for (i = rows.first; i <= rows.last; i++)
-            lines.push(session.getLine(i));
+        mouseEvent = e;
+        if (tooltipTimeout)
+            return;
+        tooltipTimeout = setTimeout(function() {
+            tooltipTimeout = null;
+            if (mouseEvent && !mouseHandler.isMousePressed)
+                showTooltip();
+            else
+                hideTooltip();
+        }, 50);
+    });
 
-        lines.sort(function(a, b) {
-            if (a.toLowerCase() < b.toLowerCase()) return -1;
-            if (a.toLowerCase() > b.toLowerCase()) return 1;
-            return 0;
-        });
+    event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
+        mouseEvent = null;
+        if (!tooltipAnnotation || tooltipTimeout)
+            return;
 
-        var deleteRange = new Range(0, 0, 0, 0);
-        for (var i = rows.first; i <= rows.last; i++) {
-            var line = session.getLine(i);
-            deleteRange.start.row = i;
-            deleteRange.end.row = i;
-            deleteRange.end.column = line.length;
-            session.replace(deleteRange, lines[i-rows.first]);
-     

<TRUNCATED>