@lingxiteam/lcdp-ueditor-react 1.0.2 → 1.0.3-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/LcdpUeditor.js +3 -1
- package/es/tools/UeditorResourceLoader.d.ts +1 -1
- package/es/tools/UeditorResourceLoader.js +18 -7
- package/lib/LcdpUeditor.js +1 -3
- package/lib/tools/UeditorResourceLoader.d.ts +1 -1
- package/lib/tools/UeditorResourceLoader.js +15 -7
- package/package.json +1 -1
- package/ueditor-resource/dialogs/anchor/anchor.html +1 -1
- package/ueditor-resource/dialogs/attachment/attachment.css +2 -715
- package/ueditor-resource/dialogs/attachment/attachment.html +6 -6
- package/ueditor-resource/dialogs/attachment/attachment.js +2 -803
- package/ueditor-resource/dialogs/audio/audio.css +2 -878
- package/ueditor-resource/dialogs/audio/audio.js +2 -815
- package/ueditor-resource/dialogs/background/background.css +2 -192
- package/ueditor-resource/dialogs/background/background.html +3 -3
- package/ueditor-resource/dialogs/background/background.js +2 -370
- package/ueditor-resource/dialogs/contentimport/contentimport.html +3 -3
- package/ueditor-resource/dialogs/contentimport/contentimport.js +2 -91
- package/ueditor-resource/dialogs/emotion/emotion.css +2 -128
- package/ueditor-resource/dialogs/emotion/emotion.html +3 -3
- package/ueditor-resource/dialogs/emotion/emotion.js +2 -186
- package/ueditor-resource/dialogs/formula/formula.html +4 -4
- package/ueditor-resource/dialogs/formula/formula.js +2 -147
- package/ueditor-resource/dialogs/help/help.css +2 -36
- package/ueditor-resource/dialogs/help/help.html +3 -3
- package/ueditor-resource/dialogs/help/help.js +2 -57
- package/ueditor-resource/dialogs/image/image.css +2 -767
- package/ueditor-resource/dialogs/image/image.js +2 -1060
- package/ueditor-resource/dialogs/insertframe/insertframe.html +2 -2
- package/ueditor-resource/dialogs/internal.js +2 -81
- package/ueditor-resource/dialogs/preview/preview.html +2 -2
- package/ueditor-resource/dialogs/scrawl/scrawl.css +2 -323
- package/ueditor-resource/dialogs/scrawl/scrawl.html +3 -3
- package/ueditor-resource/dialogs/scrawl/scrawl.js +2 -682
- package/ueditor-resource/dialogs/searchreplace/searchreplace.html +2 -2
- package/ueditor-resource/dialogs/searchreplace/searchreplace.js +2 -174
- package/ueditor-resource/dialogs/spechars/spechars.html +2 -2
- package/ueditor-resource/dialogs/spechars/spechars.js +2 -86
- package/ueditor-resource/dialogs/table/edittable.css +2 -84
- package/ueditor-resource/dialogs/table/edittable.html +3 -3
- package/ueditor-resource/dialogs/table/edittable.js +2 -241
- package/ueditor-resource/dialogs/table/edittd.html +1 -1
- package/ueditor-resource/dialogs/table/edittip.html +1 -1
- package/ueditor-resource/dialogs/template/config.js +2 -42
- package/ueditor-resource/dialogs/template/template.css +2 -98
- package/ueditor-resource/dialogs/template/template.html +4 -4
- package/ueditor-resource/dialogs/template/template.js +2 -53
- package/ueditor-resource/dialogs/video/video.css +2 -908
- package/ueditor-resource/dialogs/video/video.js +2 -867
- package/ueditor-resource/dialogs/wordimage/wordimage.html +5 -5
- package/ueditor-resource/dialogs/wordimage/wordimage.js +2 -93
- package/ueditor-resource/lang/en/en.js +2 -686
- package/ueditor-resource/lang/zh-cn/zh-cn.js +2 -748
- package/ueditor-resource/lang/zh-tw/zh-tw.js +2 -748
- package/ueditor-resource/plugins/demo/demo.js +1 -3
- package/ueditor-resource/themes/default/css/ueditor.css +2 -2148
- package/ueditor-resource/themes/default/dialog.css +2 -16
- package/ueditor-resource/themes/default/dialogbase.css +2 -131
- package/ueditor-resource/themes/iframe.css +2 -62
- package/ueditor-resource/third-party/SyntaxHighlighter/shCore.js +4 -3655
- package/ueditor-resource/third-party/SyntaxHighlighter/shCoreDefault.css +3 -1
- package/ueditor-resource/third-party/clipboard/clipboard.js +2 -753
- package/ueditor-resource/third-party/codemirror/codemirror.css +2 -105
- package/ueditor-resource/third-party/codemirror/codemirror.js +3 -3581
- package/ueditor-resource/third-party/jquery-3.5.1.js +4 -2
- package/ueditor-resource/third-party/jquery-3.5.1_1.js +4 -4314
- package/ueditor-resource/third-party/webuploader/webuploader.css +2 -87
- package/ueditor-resource/third-party/webuploader/webuploader.js +5 -4
- package/ueditor-resource/ueditor.all.js +20 -32644
- package/ueditor-resource/ueditor.config.js +2 -655
- package/ueditor-resource/ueditor.parse.js +2 -639
- package/es/LcdpUeditor.d.ts.map +0 -1
- package/es/const.d.ts.map +0 -1
- package/es/index.d.ts.map +0 -1
- package/es/tools/UeditorResourceLoader.d.ts.map +0 -1
- package/es/tools/filterHtmlNode.d.ts.map +0 -1
- package/es/tools/loadScript.d.ts.map +0 -1
- package/es/type.d.ts.map +0 -1
| @@ -1,3581 +1,3 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            //
         | 
| 3 | 
            -
            // All functions that need access to the editor's state live inside
         | 
| 4 | 
            -
            // the CodeMirror function. Below that, at the bottom of the file,
         | 
| 5 | 
            -
            // some utilities are defined.
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            // CodeMirror is the only global var we claim
         | 
| 8 | 
            -
            var CodeMirror = (function() {
         | 
| 9 | 
            -
                // This is the function that produces an editor instance. It's
         | 
| 10 | 
            -
                // closure is used to store the editor state.
         | 
| 11 | 
            -
                function CodeMirror(place, givenOptions) {
         | 
| 12 | 
            -
                    // Determine effective options based on given values and defaults.
         | 
| 13 | 
            -
                    var options = {}, defaults = CodeMirror.defaults;
         | 
| 14 | 
            -
                    for (var opt in defaults)
         | 
| 15 | 
            -
                        if (defaults.hasOwnProperty(opt))
         | 
| 16 | 
            -
                            options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    var targetDocument = options["document"];
         | 
| 19 | 
            -
                    // The element in which the editor lives.
         | 
| 20 | 
            -
                    var wrapper = targetDocument.createElement("div");
         | 
| 21 | 
            -
                    wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
         | 
| 22 | 
            -
                    // This mess creates the base DOM structure for the editor.
         | 
| 23 | 
            -
                    wrapper.innerHTML =
         | 
| 24 | 
            -
                        '<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea
         | 
| 25 | 
            -
                            '<textarea style="position: absolute; padding: 0; width: 1px;" wrap="off" ' +
         | 
| 26 | 
            -
                            'autocorrect="off" autocapitalize="off"></textarea></div>' +
         | 
| 27 | 
            -
                            '<div class="CodeMirror-scroll" tabindex="-1">' +
         | 
| 28 | 
            -
                            '<div style="position: relative">' + // Set to the height of the text, causes scrolling
         | 
| 29 | 
            -
                            '<div style="position: relative">' + // Moved around its parent to cover visible view
         | 
| 30 | 
            -
                            '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
         | 
| 31 | 
            -
                            // Provides positioning relative to (visible) text origin
         | 
| 32 | 
            -
                            '<div class="CodeMirror-lines"><div style="position: relative">' +
         | 
| 33 | 
            -
                            '<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden"></div>' +
         | 
| 34 | 
            -
                            '<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor
         | 
| 35 | 
            -
                            '<div></div>' + // This DIV contains the actual code
         | 
| 36 | 
            -
                            '</div></div></div></div></div>';
         | 
| 37 | 
            -
                    if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
         | 
| 38 | 
            -
                    // I've never seen more elegant code in my life.
         | 
| 39 | 
            -
                    var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,
         | 
| 40 | 
            -
                        scroller = wrapper.lastChild, code = scroller.firstChild,
         | 
| 41 | 
            -
                        mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
         | 
| 42 | 
            -
                        lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
         | 
| 43 | 
            -
                        cursor = measure.nextSibling, lineDiv = cursor.nextSibling;
         | 
| 44 | 
            -
                    themeChanged();
         | 
| 45 | 
            -
                    // Needed to hide big blue blinking cursor on Mobile Safari
         | 
| 46 | 
            -
                    if (/AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent)) input.style.width = "0px";
         | 
| 47 | 
            -
                    if (!webkit) lineSpace.draggable = true;
         | 
| 48 | 
            -
                    if (options.tabindex != null) input.tabIndex = options.tabindex;
         | 
| 49 | 
            -
                    if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                    // Check for problem with IE innerHTML not working when we have a
         | 
| 52 | 
            -
                    // P (or similar) parent node.
         | 
| 53 | 
            -
                    try { stringWidth("x"); }
         | 
| 54 | 
            -
                    catch (e) {
         | 
| 55 | 
            -
                        if (e.message.match(/runtime/i))
         | 
| 56 | 
            -
                            e = new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)");
         | 
| 57 | 
            -
                        throw e;
         | 
| 58 | 
            -
                    }
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                    // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
         | 
| 61 | 
            -
                    var poll = new Delayed(), highlight = new Delayed(), blinker;
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                    // mode holds a mode API object. doc is the tree of Line objects,
         | 
| 64 | 
            -
                    // work an array of lines that should be parsed, and history the
         | 
| 65 | 
            -
                    // undo history (instance of History constructor).
         | 
| 66 | 
            -
                    var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), work, focused;
         | 
| 67 | 
            -
                    loadMode();
         | 
| 68 | 
            -
                    // The selection. These are always maintained to point at valid
         | 
| 69 | 
            -
                    // positions. Inverted is used to remember that the user is
         | 
| 70 | 
            -
                    // selecting bottom-to-top.
         | 
| 71 | 
            -
                    var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
         | 
| 72 | 
            -
                    // Selection-related flags. shiftSelecting obviously tracks
         | 
| 73 | 
            -
                    // whether the user is holding shift.
         | 
| 74 | 
            -
                    var shiftSelecting, lastClick, lastDoubleClick, draggingText, overwrite = false;
         | 
| 75 | 
            -
                    // Variables used by startOperation/endOperation to track what
         | 
| 76 | 
            -
                    // happened during the operation.
         | 
| 77 | 
            -
                    var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone,
         | 
| 78 | 
            -
                        gutterDirty, callbacks;
         | 
| 79 | 
            -
                    // Current visible range (may be bigger than the view window).
         | 
| 80 | 
            -
                    var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
         | 
| 81 | 
            -
                    // bracketHighlighted is used to remember that a backet has been
         | 
| 82 | 
            -
                    // marked.
         | 
| 83 | 
            -
                    var bracketHighlighted;
         | 
| 84 | 
            -
                    // Tracks the maximum line length so that the horizontal scrollbar
         | 
| 85 | 
            -
                    // can be kept static when scrolling.
         | 
| 86 | 
            -
                    var maxLine = "", maxWidth, tabText = computeTabText();
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                    // Initialize the content.
         | 
| 89 | 
            -
                    operation(function(){setValue(options.value || ""); updateInput = false;})();
         | 
| 90 | 
            -
                    var history = new History();
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                    // Register our event handlers.
         | 
| 93 | 
            -
                    connect(scroller, "mousedown", operation(onMouseDown));
         | 
| 94 | 
            -
                    connect(scroller, "dblclick", operation(onDoubleClick));
         | 
| 95 | 
            -
                    connect(lineSpace, "dragstart", onDragStart);
         | 
| 96 | 
            -
                    connect(lineSpace, "selectstart", e_preventDefault);
         | 
| 97 | 
            -
                    // Gecko browsers fire contextmenu *after* opening the menu, at
         | 
| 98 | 
            -
                    // which point we can't mess with it anymore. Context menu is
         | 
| 99 | 
            -
                    // handled in onMouseDown for Gecko.
         | 
| 100 | 
            -
                    if (!gecko) connect(scroller, "contextmenu", onContextMenu);
         | 
| 101 | 
            -
                    connect(scroller, "scroll", function() {
         | 
| 102 | 
            -
                        updateDisplay([]);
         | 
| 103 | 
            -
                        if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
         | 
| 104 | 
            -
                        if (options.onScroll) options.onScroll(instance);
         | 
| 105 | 
            -
                    });
         | 
| 106 | 
            -
                    connect(window, "resize", function() {updateDisplay(true);});
         | 
| 107 | 
            -
                    connect(input, "keyup", operation(onKeyUp));
         | 
| 108 | 
            -
                    connect(input, "input", fastPoll);
         | 
| 109 | 
            -
                    connect(input, "keydown", operation(onKeyDown));
         | 
| 110 | 
            -
                    connect(input, "keypress", operation(onKeyPress));
         | 
| 111 | 
            -
                    connect(input, "focus", onFocus);
         | 
| 112 | 
            -
                    connect(input, "blur", onBlur);
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                    connect(scroller, "dragenter", e_stop);
         | 
| 115 | 
            -
                    connect(scroller, "dragover", e_stop);
         | 
| 116 | 
            -
                    connect(scroller, "drop", operation(onDrop));
         | 
| 117 | 
            -
                    connect(scroller, "paste", function(){focusInput(); fastPoll();});
         | 
| 118 | 
            -
                    connect(input, "paste", fastPoll);
         | 
| 119 | 
            -
                    connect(input, "cut", operation(function(){replaceSelection("");}));
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                    // IE throws unspecified error in certain cases, when
         | 
| 122 | 
            -
                    // trying to access activeElement before onload
         | 
| 123 | 
            -
                    var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
         | 
| 124 | 
            -
                    if (hasFocus) setTimeout(onFocus, 20);
         | 
| 125 | 
            -
                    else onBlur();
         | 
| 126 | 
            -
             | 
| 127 | 
            -
                    function isLine(l) {return l >= 0 && l < doc.size;}
         | 
| 128 | 
            -
                    // The instance object that we'll return. Mostly calls out to
         | 
| 129 | 
            -
                    // local functions in the CodeMirror function. Some do some extra
         | 
| 130 | 
            -
                    // range checking and/or clipping. operation is used to wrap the
         | 
| 131 | 
            -
                    // call so that changes it makes are tracked, and the display is
         | 
| 132 | 
            -
                    // updated afterwards.
         | 
| 133 | 
            -
                    var instance = wrapper.CodeMirror = {
         | 
| 134 | 
            -
                        getValue: getValue,
         | 
| 135 | 
            -
                        setValue: operation(setValue),
         | 
| 136 | 
            -
                        getSelection: getSelection,
         | 
| 137 | 
            -
                        replaceSelection: operation(replaceSelection),
         | 
| 138 | 
            -
                        focus: function(){focusInput(); onFocus(); fastPoll();},
         | 
| 139 | 
            -
                        setOption: function(option, value) {
         | 
| 140 | 
            -
                            var oldVal = options[option];
         | 
| 141 | 
            -
                            options[option] = value;
         | 
| 142 | 
            -
                            if (option == "mode" || option == "indentUnit") loadMode();
         | 
| 143 | 
            -
                            else if (option == "readOnly" && value) {onBlur(); input.blur();}
         | 
| 144 | 
            -
                            else if (option == "theme") themeChanged();
         | 
| 145 | 
            -
                            else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
         | 
| 146 | 
            -
                            else if (option == "tabSize") operation(tabsChanged)();
         | 
| 147 | 
            -
                            if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme")
         | 
| 148 | 
            -
                                operation(gutterChanged)();
         | 
| 149 | 
            -
                        },
         | 
| 150 | 
            -
                        getOption: function(option) {return options[option];},
         | 
| 151 | 
            -
                        undo: operation(undo),
         | 
| 152 | 
            -
                        redo: operation(redo),
         | 
| 153 | 
            -
                        indentLine: operation(function(n, dir) {
         | 
| 154 | 
            -
                            if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract");
         | 
| 155 | 
            -
                        }),
         | 
| 156 | 
            -
                        indentSelection: operation(indentSelected),
         | 
| 157 | 
            -
                        historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
         | 
| 158 | 
            -
                        clearHistory: function() {history = new History();},
         | 
| 159 | 
            -
                        matchBrackets: operation(function(){matchBrackets(true);}),
         | 
| 160 | 
            -
                        getTokenAt: operation(function(pos) {
         | 
| 161 | 
            -
                            pos = clipPos(pos);
         | 
| 162 | 
            -
                            return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), pos.ch);
         | 
| 163 | 
            -
                        }),
         | 
| 164 | 
            -
                        getStateAfter: function(line) {
         | 
| 165 | 
            -
                            line = clipLine(line == null ? doc.size - 1: line);
         | 
| 166 | 
            -
                            return getStateBefore(line + 1);
         | 
| 167 | 
            -
                        },
         | 
| 168 | 
            -
                        cursorCoords: function(start){
         | 
| 169 | 
            -
                            if (start == null) start = sel.inverted;
         | 
| 170 | 
            -
                            return pageCoords(start ? sel.from : sel.to);
         | 
| 171 | 
            -
                        },
         | 
| 172 | 
            -
                        charCoords: function(pos){return pageCoords(clipPos(pos));},
         | 
| 173 | 
            -
                        coordsChar: function(coords) {
         | 
| 174 | 
            -
                            var off = eltOffset(lineSpace);
         | 
| 175 | 
            -
                            return coordsChar(coords.x - off.left, coords.y - off.top);
         | 
| 176 | 
            -
                        },
         | 
| 177 | 
            -
                        markText: operation(markText),
         | 
| 178 | 
            -
                        setBookmark: setBookmark,
         | 
| 179 | 
            -
                        setMarker: operation(addGutterMarker),
         | 
| 180 | 
            -
                        clearMarker: operation(removeGutterMarker),
         | 
| 181 | 
            -
                        setLineClass: operation(setLineClass),
         | 
| 182 | 
            -
                        hideLine: operation(function(h) {return setLineHidden(h, true);}),
         | 
| 183 | 
            -
                        showLine: operation(function(h) {return setLineHidden(h, false);}),
         | 
| 184 | 
            -
                        onDeleteLine: function(line, f) {
         | 
| 185 | 
            -
                            if (typeof line == "number") {
         | 
| 186 | 
            -
                                if (!isLine(line)) return null;
         | 
| 187 | 
            -
                                line = getLine(line);
         | 
| 188 | 
            -
                            }
         | 
| 189 | 
            -
                            (line.handlers || (line.handlers = [])).push(f);
         | 
| 190 | 
            -
                            return line;
         | 
| 191 | 
            -
                        },
         | 
| 192 | 
            -
                        lineInfo: lineInfo,
         | 
| 193 | 
            -
                        addWidget: function(pos, node, scroll, vert, horiz) {
         | 
| 194 | 
            -
                            pos = localCoords(clipPos(pos));
         | 
| 195 | 
            -
                            var top = pos.yBot, left = pos.x;
         | 
| 196 | 
            -
                            node.style.position = "absolute";
         | 
| 197 | 
            -
                            code.appendChild(node);
         | 
| 198 | 
            -
                            if (vert == "over") top = pos.y;
         | 
| 199 | 
            -
                            else if (vert == "near") {
         | 
| 200 | 
            -
                                var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
         | 
| 201 | 
            -
                                    hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
         | 
| 202 | 
            -
                                if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
         | 
| 203 | 
            -
                                    top = pos.y - node.offsetHeight;
         | 
| 204 | 
            -
                                if (left + node.offsetWidth > hspace)
         | 
| 205 | 
            -
                                    left = hspace - node.offsetWidth;
         | 
| 206 | 
            -
                            }
         | 
| 207 | 
            -
                            node.style.top = (top + paddingTop()) + "px";
         | 
| 208 | 
            -
                            node.style.left = node.style.right = "";
         | 
| 209 | 
            -
                            if (horiz == "right") {
         | 
| 210 | 
            -
                                left = code.clientWidth - node.offsetWidth;
         | 
| 211 | 
            -
                                node.style.right = "0px";
         | 
| 212 | 
            -
                            } else {
         | 
| 213 | 
            -
                                if (horiz == "left") left = 0;
         | 
| 214 | 
            -
                                else if (horiz == "middle") left = (code.clientWidth - node.offsetWidth) / 2;
         | 
| 215 | 
            -
                                node.style.left = (left + paddingLeft()) + "px";
         | 
| 216 | 
            -
                            }
         | 
| 217 | 
            -
                            if (scroll)
         | 
| 218 | 
            -
                                scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
         | 
| 219 | 
            -
                        },
         | 
| 220 | 
            -
             | 
| 221 | 
            -
                        lineCount: function() {return doc.size;},
         | 
| 222 | 
            -
                        clipPos: clipPos,
         | 
| 223 | 
            -
                        getCursor: function(start) {
         | 
| 224 | 
            -
                            if (start == null) start = sel.inverted;
         | 
| 225 | 
            -
                            return copyPos(start ? sel.from : sel.to);
         | 
| 226 | 
            -
                        },
         | 
| 227 | 
            -
                        somethingSelected: function() {return !posEq(sel.from, sel.to);},
         | 
| 228 | 
            -
                        setCursor: operation(function(line, ch, user) {
         | 
| 229 | 
            -
                            if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch, user);
         | 
| 230 | 
            -
                            else setCursor(line, ch, user);
         | 
| 231 | 
            -
                        }),
         | 
| 232 | 
            -
                        setSelection: operation(function(from, to, user) {
         | 
| 233 | 
            -
                            (user ? setSelectionUser : setSelection)(clipPos(from), clipPos(to || from));
         | 
| 234 | 
            -
                        }),
         | 
| 235 | 
            -
                        getLine: function(line) {if (isLine(line)) return getLine(line).text;},
         | 
| 236 | 
            -
                        getLineHandle: function(line) {if (isLine(line)) return getLine(line);},
         | 
| 237 | 
            -
                        setLine: operation(function(line, text) {
         | 
| 238 | 
            -
                            if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
         | 
| 239 | 
            -
                        }),
         | 
| 240 | 
            -
                        removeLine: operation(function(line) {
         | 
| 241 | 
            -
                            if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
         | 
| 242 | 
            -
                        }),
         | 
| 243 | 
            -
                        replaceRange: operation(replaceRange),
         | 
| 244 | 
            -
                        getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
         | 
| 245 | 
            -
             | 
| 246 | 
            -
                        execCommand: function(cmd) {return commands[cmd](instance);},
         | 
| 247 | 
            -
                        // Stuff used by commands, probably not much use to outside code.
         | 
| 248 | 
            -
                        moveH: operation(moveH),
         | 
| 249 | 
            -
                        deleteH: operation(deleteH),
         | 
| 250 | 
            -
                        moveV: operation(moveV),
         | 
| 251 | 
            -
                        toggleOverwrite: function() {overwrite = !overwrite;},
         | 
| 252 | 
            -
             | 
| 253 | 
            -
                        posFromIndex: function(off) {
         | 
| 254 | 
            -
                            var lineNo = 0, ch;
         | 
| 255 | 
            -
                            doc.iter(0, doc.size, function(line) {
         | 
| 256 | 
            -
                                var sz = line.text.length + 1;
         | 
| 257 | 
            -
                                if (sz > off) { ch = off; return true; }
         | 
| 258 | 
            -
                                off -= sz;
         | 
| 259 | 
            -
                                ++lineNo;
         | 
| 260 | 
            -
                            });
         | 
| 261 | 
            -
                            return clipPos({line: lineNo, ch: ch});
         | 
| 262 | 
            -
                        },
         | 
| 263 | 
            -
                        indexFromPos: function (coords) {
         | 
| 264 | 
            -
                            if (coords.line < 0 || coords.ch < 0) return 0;
         | 
| 265 | 
            -
                            var index = coords.ch;
         | 
| 266 | 
            -
                            doc.iter(0, coords.line, function (line) {
         | 
| 267 | 
            -
                                index += line.text.length + 1;
         | 
| 268 | 
            -
                            });
         | 
| 269 | 
            -
                            return index;
         | 
| 270 | 
            -
                        },
         | 
| 271 | 
            -
             | 
| 272 | 
            -
                        operation: function(f){return operation(f)();},
         | 
| 273 | 
            -
                        refresh: function(){updateDisplay(true);},
         | 
| 274 | 
            -
                        getInputField: function(){return input;},
         | 
| 275 | 
            -
                        getWrapperElement: function(){return wrapper;},
         | 
| 276 | 
            -
                        getScrollerElement: function(){return scroller;},
         | 
| 277 | 
            -
                        getGutterElement: function(){return gutter;}
         | 
| 278 | 
            -
                    };
         | 
| 279 | 
            -
             | 
| 280 | 
            -
                    function getLine(n) { return getLineAt(doc, n); }
         | 
| 281 | 
            -
                    function updateLineHeight(line, height) {
         | 
| 282 | 
            -
                        gutterDirty = true;
         | 
| 283 | 
            -
                        var diff = height - line.height;
         | 
| 284 | 
            -
                        for (var n = line; n; n = n.parent) n.height += diff;
         | 
| 285 | 
            -
                    }
         | 
| 286 | 
            -
             | 
| 287 | 
            -
                    function setValue(code) {
         | 
| 288 | 
            -
                        var top = {line: 0, ch: 0};
         | 
| 289 | 
            -
                        updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
         | 
| 290 | 
            -
                            splitLines(code), top, top);
         | 
| 291 | 
            -
                        updateInput = true;
         | 
| 292 | 
            -
                    }
         | 
| 293 | 
            -
                    function getValue(code) {
         | 
| 294 | 
            -
                        var text = [];
         | 
| 295 | 
            -
                        doc.iter(0, doc.size, function(line) { text.push(line.text); });
         | 
| 296 | 
            -
                        return text.join("\n");
         | 
| 297 | 
            -
                    }
         | 
| 298 | 
            -
             | 
| 299 | 
            -
                    function onMouseDown(e) {
         | 
| 300 | 
            -
                        setShift(e.shiftKey);
         | 
| 301 | 
            -
                        // Check whether this is a click in a widget
         | 
| 302 | 
            -
                        for (var n = e_target(e); n != wrapper; n = n.parentNode)
         | 
| 303 | 
            -
                            if (n.parentNode == code && n != mover) return;
         | 
| 304 | 
            -
             | 
| 305 | 
            -
                        // See if this is a click in the gutter
         | 
| 306 | 
            -
                        for (var n = e_target(e); n != wrapper; n = n.parentNode)
         | 
| 307 | 
            -
                            if (n.parentNode == gutterText) {
         | 
| 308 | 
            -
                                if (options.onGutterClick)
         | 
| 309 | 
            -
                                    options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
         | 
| 310 | 
            -
                                return e_preventDefault(e);
         | 
| 311 | 
            -
                            }
         | 
| 312 | 
            -
             | 
| 313 | 
            -
                        var start = posFromMouse(e);
         | 
| 314 | 
            -
             | 
| 315 | 
            -
                        switch (e_button(e)) {
         | 
| 316 | 
            -
                            case 3:
         | 
| 317 | 
            -
                                if (gecko && !mac) onContextMenu(e);
         | 
| 318 | 
            -
                                return;
         | 
| 319 | 
            -
                            case 2:
         | 
| 320 | 
            -
                                if (start) setCursor(start.line, start.ch, true);
         | 
| 321 | 
            -
                                return;
         | 
| 322 | 
            -
                        }
         | 
| 323 | 
            -
                        // For button 1, if it was clicked inside the editor
         | 
| 324 | 
            -
                        // (posFromMouse returning non-null), we have to adjust the
         | 
| 325 | 
            -
                        // selection.
         | 
| 326 | 
            -
                        if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
         | 
| 327 | 
            -
             | 
| 328 | 
            -
                        if (!focused) onFocus();
         | 
| 329 | 
            -
             | 
| 330 | 
            -
                        var now = +new Date;
         | 
| 331 | 
            -
                        if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
         | 
| 332 | 
            -
                            e_preventDefault(e);
         | 
| 333 | 
            -
                            setTimeout(focusInput, 20);
         | 
| 334 | 
            -
                            return selectLine(start.line);
         | 
| 335 | 
            -
                        } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
         | 
| 336 | 
            -
                            lastDoubleClick = {time: now, pos: start};
         | 
| 337 | 
            -
                            e_preventDefault(e);
         | 
| 338 | 
            -
                            return selectWordAt(start);
         | 
| 339 | 
            -
                        } else { lastClick = {time: now, pos: start}; }
         | 
| 340 | 
            -
             | 
| 341 | 
            -
                        var last = start, going;
         | 
| 342 | 
            -
                        if (dragAndDrop && !posEq(sel.from, sel.to) &&
         | 
| 343 | 
            -
                            !posLess(start, sel.from) && !posLess(sel.to, start)) {
         | 
| 344 | 
            -
                            // Let the drag handler handle this.
         | 
| 345 | 
            -
                            if (webkit) lineSpace.draggable = true;
         | 
| 346 | 
            -
                            var up = connect(targetDocument, "mouseup", operation(function(e2) {
         | 
| 347 | 
            -
                                if (webkit) lineSpace.draggable = false;
         | 
| 348 | 
            -
                                draggingText = false;
         | 
| 349 | 
            -
                                up();
         | 
| 350 | 
            -
                                if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
         | 
| 351 | 
            -
                                    e_preventDefault(e2);
         | 
| 352 | 
            -
                                    setCursor(start.line, start.ch, true);
         | 
| 353 | 
            -
                                    focusInput();
         | 
| 354 | 
            -
                                }
         | 
| 355 | 
            -
                            }), true);
         | 
| 356 | 
            -
                            draggingText = true;
         | 
| 357 | 
            -
                            return;
         | 
| 358 | 
            -
                        }
         | 
| 359 | 
            -
                        e_preventDefault(e);
         | 
| 360 | 
            -
                        setCursor(start.line, start.ch, true);
         | 
| 361 | 
            -
             | 
| 362 | 
            -
                        function extend(e) {
         | 
| 363 | 
            -
                            var cur = posFromMouse(e, true);
         | 
| 364 | 
            -
                            if (cur && !posEq(cur, last)) {
         | 
| 365 | 
            -
                                if (!focused) onFocus();
         | 
| 366 | 
            -
                                last = cur;
         | 
| 367 | 
            -
                                setSelectionUser(start, cur);
         | 
| 368 | 
            -
                                updateInput = false;
         | 
| 369 | 
            -
                                var visible = visibleLines();
         | 
| 370 | 
            -
                                if (cur.line >= visible.to || cur.line < visible.from)
         | 
| 371 | 
            -
                                    going = setTimeout(operation(function(){extend(e);}), 150);
         | 
| 372 | 
            -
                            }
         | 
| 373 | 
            -
                        }
         | 
| 374 | 
            -
             | 
| 375 | 
            -
                        var move = connect(targetDocument, "mousemove", operation(function(e) {
         | 
| 376 | 
            -
                            clearTimeout(going);
         | 
| 377 | 
            -
                            e_preventDefault(e);
         | 
| 378 | 
            -
                            extend(e);
         | 
| 379 | 
            -
                        }), true);
         | 
| 380 | 
            -
                        var up = connect(targetDocument, "mouseup", operation(function(e) {
         | 
| 381 | 
            -
                            clearTimeout(going);
         | 
| 382 | 
            -
                            var cur = posFromMouse(e);
         | 
| 383 | 
            -
                            if (cur) setSelectionUser(start, cur);
         | 
| 384 | 
            -
                            e_preventDefault(e);
         | 
| 385 | 
            -
                            focusInput();
         | 
| 386 | 
            -
                            updateInput = true;
         | 
| 387 | 
            -
                            move(); up();
         | 
| 388 | 
            -
                        }), true);
         | 
| 389 | 
            -
                    }
         | 
| 390 | 
            -
                    function onDoubleClick(e) {
         | 
| 391 | 
            -
                        for (var n = e_target(e); n != wrapper; n = n.parentNode)
         | 
| 392 | 
            -
                            if (n.parentNode == gutterText) return e_preventDefault(e);
         | 
| 393 | 
            -
                        var start = posFromMouse(e);
         | 
| 394 | 
            -
                        if (!start) return;
         | 
| 395 | 
            -
                        lastDoubleClick = {time: +new Date, pos: start};
         | 
| 396 | 
            -
                        e_preventDefault(e);
         | 
| 397 | 
            -
                        selectWordAt(start);
         | 
| 398 | 
            -
                    }
         | 
| 399 | 
            -
                    function onDrop(e) {
         | 
| 400 | 
            -
                        e.preventDefault();
         | 
| 401 | 
            -
                        var pos = posFromMouse(e, true), files = e.dataTransfer.files;
         | 
| 402 | 
            -
                        if (!pos || options.readOnly) return;
         | 
| 403 | 
            -
                        if (files && files.length && window.FileReader && window.File) {
         | 
| 404 | 
            -
                            function loadFile(file, i) {
         | 
| 405 | 
            -
                                var reader = new FileReader;
         | 
| 406 | 
            -
                                reader.onload = function() {
         | 
| 407 | 
            -
                                    text[i] = reader.result;
         | 
| 408 | 
            -
                                    if (++read == n) {
         | 
| 409 | 
            -
                                        pos = clipPos(pos);
         | 
| 410 | 
            -
                                        operation(function() {
         | 
| 411 | 
            -
                                            var end = replaceRange(text.join(""), pos, pos);
         | 
| 412 | 
            -
                                            setSelectionUser(pos, end);
         | 
| 413 | 
            -
                                        })();
         | 
| 414 | 
            -
                                    }
         | 
| 415 | 
            -
                                };
         | 
| 416 | 
            -
                                reader.readAsText(file);
         | 
| 417 | 
            -
                            }
         | 
| 418 | 
            -
                            var n = files.length, text = Array(n), read = 0;
         | 
| 419 | 
            -
                            for (var i = 0; i < n; ++i) loadFile(files[i], i);
         | 
| 420 | 
            -
                        }
         | 
| 421 | 
            -
                        else {
         | 
| 422 | 
            -
                            try {
         | 
| 423 | 
            -
                                var text = e.dataTransfer.getData("Text");
         | 
| 424 | 
            -
                                if (text) {
         | 
| 425 | 
            -
                                    var end = replaceRange(text, pos, pos);
         | 
| 426 | 
            -
                                    var curFrom = sel.from, curTo = sel.to;
         | 
| 427 | 
            -
                                    setSelectionUser(pos, end);
         | 
| 428 | 
            -
                                    if (draggingText) replaceRange("", curFrom, curTo);
         | 
| 429 | 
            -
                                    focusInput();
         | 
| 430 | 
            -
                                }
         | 
| 431 | 
            -
                            }
         | 
| 432 | 
            -
                            catch(e){}
         | 
| 433 | 
            -
                        }
         | 
| 434 | 
            -
                    }
         | 
| 435 | 
            -
                    function onDragStart(e) {
         | 
| 436 | 
            -
                        var txt = getSelection();
         | 
| 437 | 
            -
                        // This will reset escapeElement
         | 
| 438 | 
            -
                        htmlEscape(txt);
         | 
| 439 | 
            -
                        e.dataTransfer.setDragImage(escapeElement, 0, 0);
         | 
| 440 | 
            -
                        e.dataTransfer.setData("Text", txt);
         | 
| 441 | 
            -
                    }
         | 
| 442 | 
            -
                    function handleKeyBinding(e) {
         | 
| 443 | 
            -
                        var name = keyNames[e.keyCode], next = keyMap[options.keyMap].auto, bound, dropShift;
         | 
| 444 | 
            -
                        if (name == null || e.altGraphKey) {
         | 
| 445 | 
            -
                            if (next) options.keyMap = next;
         | 
| 446 | 
            -
                            return null;
         | 
| 447 | 
            -
                        }
         | 
| 448 | 
            -
                        if (e.altKey) name = "Alt-" + name;
         | 
| 449 | 
            -
                        if (e.ctrlKey) name = "Ctrl-" + name;
         | 
| 450 | 
            -
                        if (e.metaKey) name = "Cmd-" + name;
         | 
| 451 | 
            -
                        if (e.shiftKey && (bound = lookupKey("Shift-" + name, options.extraKeys, options.keyMap))) {
         | 
| 452 | 
            -
                            dropShift = true;
         | 
| 453 | 
            -
                        } else {
         | 
| 454 | 
            -
                            bound = lookupKey(name, options.extraKeys, options.keyMap);
         | 
| 455 | 
            -
                        }
         | 
| 456 | 
            -
                        if (typeof bound == "string") {
         | 
| 457 | 
            -
                            if (commands.propertyIsEnumerable(bound)) bound = commands[bound];
         | 
| 458 | 
            -
                            else bound = null;
         | 
| 459 | 
            -
                        }
         | 
| 460 | 
            -
                        if (next && (bound || !isModifierKey(e))) options.keyMap = next;
         | 
| 461 | 
            -
                        if (!bound) return false;
         | 
| 462 | 
            -
                        if (dropShift) {
         | 
| 463 | 
            -
                            var prevShift = shiftSelecting;
         | 
| 464 | 
            -
                            shiftSelecting = null;
         | 
| 465 | 
            -
                            bound(instance);
         | 
| 466 | 
            -
                            shiftSelecting = prevShift;
         | 
| 467 | 
            -
                        } else bound(instance);
         | 
| 468 | 
            -
                        e_preventDefault(e);
         | 
| 469 | 
            -
                        return true;
         | 
| 470 | 
            -
                    }
         | 
| 471 | 
            -
                    var lastStoppedKey = null;
         | 
| 472 | 
            -
                    function onKeyDown(e) {
         | 
| 473 | 
            -
                        if (!focused) onFocus();
         | 
| 474 | 
            -
                        var code = e.keyCode;
         | 
| 475 | 
            -
                        // IE does strange things with escape.
         | 
| 476 | 
            -
                        if (ie && code == 27) { e.returnValue = false; }
         | 
| 477 | 
            -
                        setShift(code == 16 || e.shiftKey);
         | 
| 478 | 
            -
                        // First give onKeyEvent option a chance to handle this.
         | 
| 479 | 
            -
                        if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
         | 
| 480 | 
            -
                        var handled = handleKeyBinding(e);
         | 
| 481 | 
            -
                        if (window.opera) {
         | 
| 482 | 
            -
                            lastStoppedKey = handled ? e.keyCode : null;
         | 
| 483 | 
            -
                            // Opera has no cut event... we try to at least catch the key combo
         | 
| 484 | 
            -
                            if (!handled && (mac ? e.metaKey : e.ctrlKey) && e.keyCode == 88)
         | 
| 485 | 
            -
                                replaceSelection("");
         | 
| 486 | 
            -
                        }
         | 
| 487 | 
            -
                    }
         | 
| 488 | 
            -
                    function onKeyPress(e) {
         | 
| 489 | 
            -
                        if (window.opera && e.keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
         | 
| 490 | 
            -
                        if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
         | 
| 491 | 
            -
                        if (window.opera && !e.which && handleKeyBinding(e)) return;
         | 
| 492 | 
            -
                        if (options.electricChars && mode.electricChars) {
         | 
| 493 | 
            -
                            var ch = String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode);
         | 
| 494 | 
            -
                            if (mode.electricChars.indexOf(ch) > -1)
         | 
| 495 | 
            -
                                setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 75);
         | 
| 496 | 
            -
                        }
         | 
| 497 | 
            -
                        fastPoll();
         | 
| 498 | 
            -
                    }
         | 
| 499 | 
            -
                    function onKeyUp(e) {
         | 
| 500 | 
            -
                        if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
         | 
| 501 | 
            -
                        if (e.keyCode == 16) shiftSelecting = null;
         | 
| 502 | 
            -
                    }
         | 
| 503 | 
            -
             | 
| 504 | 
            -
                    function onFocus() {
         | 
| 505 | 
            -
                        if (options.readOnly) return;
         | 
| 506 | 
            -
                        if (!focused) {
         | 
| 507 | 
            -
                            if (options.onFocus) options.onFocus(instance);
         | 
| 508 | 
            -
                            focused = true;
         | 
| 509 | 
            -
                            if (wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
         | 
| 510 | 
            -
                                wrapper.className += " CodeMirror-focused";
         | 
| 511 | 
            -
                            if (!leaveInputAlone) resetInput(true);
         | 
| 512 | 
            -
                        }
         | 
| 513 | 
            -
                        slowPoll();
         | 
| 514 | 
            -
                        restartBlink();
         | 
| 515 | 
            -
                    }
         | 
| 516 | 
            -
                    function onBlur() {
         | 
| 517 | 
            -
                        if (focused) {
         | 
| 518 | 
            -
                            if (options.onBlur) options.onBlur(instance);
         | 
| 519 | 
            -
                            focused = false;
         | 
| 520 | 
            -
                            wrapper.className = wrapper.className.replace(" CodeMirror-focused", "");
         | 
| 521 | 
            -
                        }
         | 
| 522 | 
            -
                        clearInterval(blinker);
         | 
| 523 | 
            -
                        setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
         | 
| 524 | 
            -
                    }
         | 
| 525 | 
            -
             | 
| 526 | 
            -
                    // Replace the range from from to to by the strings in newText.
         | 
| 527 | 
            -
                    // Afterwards, set the selection to selFrom, selTo.
         | 
| 528 | 
            -
                    function updateLines(from, to, newText, selFrom, selTo) {
         | 
| 529 | 
            -
                        if (history) {
         | 
| 530 | 
            -
                            var old = [];
         | 
| 531 | 
            -
                            doc.iter(from.line, to.line + 1, function(line) { old.push(line.text); });
         | 
| 532 | 
            -
                            history.addChange(from.line, newText.length, old);
         | 
| 533 | 
            -
                            while (history.done.length > options.undoDepth) history.done.shift();
         | 
| 534 | 
            -
                        }
         | 
| 535 | 
            -
                        updateLinesNoUndo(from, to, newText, selFrom, selTo);
         | 
| 536 | 
            -
                    }
         | 
| 537 | 
            -
                    function unredoHelper(from, to) {
         | 
| 538 | 
            -
                        var change = from.pop();
         | 
| 539 | 
            -
                        if (change) {
         | 
| 540 | 
            -
                            var replaced = [], end = change.start + change.added;
         | 
| 541 | 
            -
                            doc.iter(change.start, end, function(line) { replaced.push(line.text); });
         | 
| 542 | 
            -
                            to.push({start: change.start, added: change.old.length, old: replaced});
         | 
| 543 | 
            -
                            var pos = clipPos({line: change.start + change.old.length - 1,
         | 
| 544 | 
            -
                                ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});
         | 
| 545 | 
            -
                            updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length}, change.old, pos, pos);
         | 
| 546 | 
            -
                            updateInput = true;
         | 
| 547 | 
            -
                        }
         | 
| 548 | 
            -
                    }
         | 
| 549 | 
            -
                    function undo() {unredoHelper(history.done, history.undone);}
         | 
| 550 | 
            -
                    function redo() {unredoHelper(history.undone, history.done);}
         | 
| 551 | 
            -
             | 
| 552 | 
            -
                    function updateLinesNoUndo(from, to, newText, selFrom, selTo) {
         | 
| 553 | 
            -
                        var recomputeMaxLength = false, maxLineLength = maxLine.length;
         | 
| 554 | 
            -
                        if (!options.lineWrapping)
         | 
| 555 | 
            -
                            doc.iter(from.line, to.line, function(line) {
         | 
| 556 | 
            -
                                if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
         | 
| 557 | 
            -
                            });
         | 
| 558 | 
            -
                        if (from.line != to.line || newText.length > 1) gutterDirty = true;
         | 
| 559 | 
            -
             | 
| 560 | 
            -
                        var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
         | 
| 561 | 
            -
                        // First adjust the line structure, taking some care to leave highlighting intact.
         | 
| 562 | 
            -
                        if (from.ch == 0 && to.ch == 0 && newText[newText.length - 1] == "") {
         | 
| 563 | 
            -
                            // This is a whole-line replace. Treated specially to make
         | 
| 564 | 
            -
                            // sure line objects move the way they are supposed to.
         | 
| 565 | 
            -
                            var added = [], prevLine = null;
         | 
| 566 | 
            -
                            if (from.line) {
         | 
| 567 | 
            -
                                prevLine = getLine(from.line - 1);
         | 
| 568 | 
            -
                                prevLine.fixMarkEnds(lastLine);
         | 
| 569 | 
            -
                            } else lastLine.fixMarkStarts();
         | 
| 570 | 
            -
                            for (var i = 0, e = newText.length - 1; i < e; ++i)
         | 
| 571 | 
            -
                                added.push(Line.inheritMarks(newText[i], prevLine));
         | 
| 572 | 
            -
                            if (nlines) doc.remove(from.line, nlines, callbacks);
         | 
| 573 | 
            -
                            if (added.length) doc.insert(from.line, added);
         | 
| 574 | 
            -
                        } else if (firstLine == lastLine) {
         | 
| 575 | 
            -
                            if (newText.length == 1)
         | 
| 576 | 
            -
                                firstLine.replace(from.ch, to.ch, newText[0]);
         | 
| 577 | 
            -
                            else {
         | 
| 578 | 
            -
                                lastLine = firstLine.split(to.ch, newText[newText.length-1]);
         | 
| 579 | 
            -
                                firstLine.replace(from.ch, null, newText[0]);
         | 
| 580 | 
            -
                                firstLine.fixMarkEnds(lastLine);
         | 
| 581 | 
            -
                                var added = [];
         | 
| 582 | 
            -
                                for (var i = 1, e = newText.length - 1; i < e; ++i)
         | 
| 583 | 
            -
                                    added.push(Line.inheritMarks(newText[i], firstLine));
         | 
| 584 | 
            -
                                added.push(lastLine);
         | 
| 585 | 
            -
                                doc.insert(from.line + 1, added);
         | 
| 586 | 
            -
                            }
         | 
| 587 | 
            -
                        } else if (newText.length == 1) {
         | 
| 588 | 
            -
                            firstLine.replace(from.ch, null, newText[0]);
         | 
| 589 | 
            -
                            lastLine.replace(null, to.ch, "");
         | 
| 590 | 
            -
                            firstLine.append(lastLine);
         | 
| 591 | 
            -
                            doc.remove(from.line + 1, nlines, callbacks);
         | 
| 592 | 
            -
                        } else {
         | 
| 593 | 
            -
                            var added = [];
         | 
| 594 | 
            -
                            firstLine.replace(from.ch, null, newText[0]);
         | 
| 595 | 
            -
                            lastLine.replace(null, to.ch, newText[newText.length-1]);
         | 
| 596 | 
            -
                            firstLine.fixMarkEnds(lastLine);
         | 
| 597 | 
            -
                            for (var i = 1, e = newText.length - 1; i < e; ++i)
         | 
| 598 | 
            -
                                added.push(Line.inheritMarks(newText[i], firstLine));
         | 
| 599 | 
            -
                            if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);
         | 
| 600 | 
            -
                            doc.insert(from.line + 1, added);
         | 
| 601 | 
            -
                        }
         | 
| 602 | 
            -
                        if (options.lineWrapping) {
         | 
| 603 | 
            -
                            var perLine = scroller.clientWidth / charWidth() - 3;
         | 
| 604 | 
            -
                            doc.iter(from.line, from.line + newText.length, function(line) {
         | 
| 605 | 
            -
                                if (line.hidden) return;
         | 
| 606 | 
            -
                                var guess = Math.ceil(line.text.length / perLine) || 1;
         | 
| 607 | 
            -
                                if (guess != line.height) updateLineHeight(line, guess);
         | 
| 608 | 
            -
                            });
         | 
| 609 | 
            -
                        } else {
         | 
| 610 | 
            -
                            doc.iter(from.line, i + newText.length, function(line) {
         | 
| 611 | 
            -
                                var l = line.text;
         | 
| 612 | 
            -
                                if (l.length > maxLineLength) {
         | 
| 613 | 
            -
                                    maxLine = l; maxLineLength = l.length; maxWidth = null;
         | 
| 614 | 
            -
                                    recomputeMaxLength = false;
         | 
| 615 | 
            -
                                }
         | 
| 616 | 
            -
                            });
         | 
| 617 | 
            -
                            if (recomputeMaxLength) {
         | 
| 618 | 
            -
                                maxLineLength = 0; maxLine = ""; maxWidth = null;
         | 
| 619 | 
            -
                                doc.iter(0, doc.size, function(line) {
         | 
| 620 | 
            -
                                    var l = line.text;
         | 
| 621 | 
            -
                                    if (l.length > maxLineLength) {
         | 
| 622 | 
            -
                                        maxLineLength = l.length; maxLine = l;
         | 
| 623 | 
            -
                                    }
         | 
| 624 | 
            -
                                });
         | 
| 625 | 
            -
                            }
         | 
| 626 | 
            -
                        }
         | 
| 627 | 
            -
             | 
| 628 | 
            -
                        // Add these lines to the work array, so that they will be
         | 
| 629 | 
            -
                        // highlighted. Adjust work lines if lines were added/removed.
         | 
| 630 | 
            -
                        var newWork = [], lendiff = newText.length - nlines - 1;
         | 
| 631 | 
            -
                        for (var i = 0, l = work.length; i < l; ++i) {
         | 
| 632 | 
            -
                            var task = work[i];
         | 
| 633 | 
            -
                            if (task < from.line) newWork.push(task);
         | 
| 634 | 
            -
                            else if (task > to.line) newWork.push(task + lendiff);
         | 
| 635 | 
            -
                        }
         | 
| 636 | 
            -
                        var hlEnd = from.line + Math.min(newText.length, 500);
         | 
| 637 | 
            -
                        highlightLines(from.line, hlEnd);
         | 
| 638 | 
            -
                        newWork.push(hlEnd);
         | 
| 639 | 
            -
                        work = newWork;
         | 
| 640 | 
            -
                        startWorker(100);
         | 
| 641 | 
            -
                        // Remember that these lines changed, for updating the display
         | 
| 642 | 
            -
                        changes.push({from: from.line, to: to.line + 1, diff: lendiff});
         | 
| 643 | 
            -
                        var changeObj = {from: from, to: to, text: newText};
         | 
| 644 | 
            -
                        if (textChanged) {
         | 
| 645 | 
            -
                            for (var cur = textChanged; cur.next; cur = cur.next) {}
         | 
| 646 | 
            -
                            cur.next = changeObj;
         | 
| 647 | 
            -
                        } else textChanged = changeObj;
         | 
| 648 | 
            -
             | 
| 649 | 
            -
                        // Update the selection
         | 
| 650 | 
            -
                        function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
         | 
| 651 | 
            -
                        setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));
         | 
| 652 | 
            -
             | 
| 653 | 
            -
                        // Make sure the scroll-size div has the correct height.
         | 
| 654 | 
            -
                        code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + "px";
         | 
| 655 | 
            -
                    }
         | 
| 656 | 
            -
             | 
| 657 | 
            -
                    function replaceRange(code, from, to) {
         | 
| 658 | 
            -
                        from = clipPos(from);
         | 
| 659 | 
            -
                        if (!to) to = from; else to = clipPos(to);
         | 
| 660 | 
            -
                        code = splitLines(code);
         | 
| 661 | 
            -
                        function adjustPos(pos) {
         | 
| 662 | 
            -
                            if (posLess(pos, from)) return pos;
         | 
| 663 | 
            -
                            if (!posLess(to, pos)) return end;
         | 
| 664 | 
            -
                            var line = pos.line + code.length - (to.line - from.line) - 1;
         | 
| 665 | 
            -
                            var ch = pos.ch;
         | 
| 666 | 
            -
                            if (pos.line == to.line)
         | 
| 667 | 
            -
                                ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0));
         | 
| 668 | 
            -
                            return {line: line, ch: ch};
         | 
| 669 | 
            -
                        }
         | 
| 670 | 
            -
                        var end;
         | 
| 671 | 
            -
                        replaceRange1(code, from, to, function(end1) {
         | 
| 672 | 
            -
                            end = end1;
         | 
| 673 | 
            -
                            return {from: adjustPos(sel.from), to: adjustPos(sel.to)};
         | 
| 674 | 
            -
                        });
         | 
| 675 | 
            -
                        return end;
         | 
| 676 | 
            -
                    }
         | 
| 677 | 
            -
                    function replaceSelection(code, collapse) {
         | 
| 678 | 
            -
                        replaceRange1(splitLines(code), sel.from, sel.to, function(end) {
         | 
| 679 | 
            -
                            if (collapse == "end") return {from: end, to: end};
         | 
| 680 | 
            -
                            else if (collapse == "start") return {from: sel.from, to: sel.from};
         | 
| 681 | 
            -
                            else return {from: sel.from, to: end};
         | 
| 682 | 
            -
                        });
         | 
| 683 | 
            -
                    }
         | 
| 684 | 
            -
                    function replaceRange1(code, from, to, computeSel) {
         | 
| 685 | 
            -
                        var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length;
         | 
| 686 | 
            -
                        var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
         | 
| 687 | 
            -
                        updateLines(from, to, code, newSel.from, newSel.to);
         | 
| 688 | 
            -
                    }
         | 
| 689 | 
            -
             | 
| 690 | 
            -
                    function getRange(from, to) {
         | 
| 691 | 
            -
                        var l1 = from.line, l2 = to.line;
         | 
| 692 | 
            -
                        if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);
         | 
| 693 | 
            -
                        var code = [getLine(l1).text.slice(from.ch)];
         | 
| 694 | 
            -
                        doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
         | 
| 695 | 
            -
                        code.push(getLine(l2).text.slice(0, to.ch));
         | 
| 696 | 
            -
                        return code.join("\n");
         | 
| 697 | 
            -
                    }
         | 
| 698 | 
            -
                    function getSelection() {
         | 
| 699 | 
            -
                        return getRange(sel.from, sel.to);
         | 
| 700 | 
            -
                    }
         | 
| 701 | 
            -
             | 
| 702 | 
            -
                    var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
         | 
| 703 | 
            -
                    function slowPoll() {
         | 
| 704 | 
            -
                        if (pollingFast) return;
         | 
| 705 | 
            -
                        poll.set(options.pollInterval, function() {
         | 
| 706 | 
            -
                            startOperation();
         | 
| 707 | 
            -
                            readInput();
         | 
| 708 | 
            -
                            if (focused) slowPoll();
         | 
| 709 | 
            -
                            endOperation();
         | 
| 710 | 
            -
                        });
         | 
| 711 | 
            -
                    }
         | 
| 712 | 
            -
                    function fastPoll() {
         | 
| 713 | 
            -
                        var missed = false;
         | 
| 714 | 
            -
                        pollingFast = true;
         | 
| 715 | 
            -
                        function p() {
         | 
| 716 | 
            -
                            startOperation();
         | 
| 717 | 
            -
                            var changed = readInput();
         | 
| 718 | 
            -
                            if (!changed && !missed) {missed = true; poll.set(60, p);}
         | 
| 719 | 
            -
                            else {pollingFast = false; slowPoll();}
         | 
| 720 | 
            -
                            endOperation();
         | 
| 721 | 
            -
                        }
         | 
| 722 | 
            -
                        poll.set(20, p);
         | 
| 723 | 
            -
                    }
         | 
| 724 | 
            -
             | 
| 725 | 
            -
                    // Previnput is a hack to work with IME. If we reset the textarea
         | 
| 726 | 
            -
                    // on every change, that breaks IME. So we look for changes
         | 
| 727 | 
            -
                    // compared to the previous content instead. (Modern browsers have
         | 
| 728 | 
            -
                    // events that indicate IME taking place, but these are not widely
         | 
| 729 | 
            -
                    // supported or compatible enough yet to rely on.)
         | 
| 730 | 
            -
                    var prevInput = "";
         | 
| 731 | 
            -
                    function readInput() {
         | 
| 732 | 
            -
                        if (leaveInputAlone || !focused || hasSelection(input)) return false;
         | 
| 733 | 
            -
                        var text = input.value;
         | 
| 734 | 
            -
                        if (text == prevInput) return false;
         | 
| 735 | 
            -
                        shiftSelecting = null;
         | 
| 736 | 
            -
                        var same = 0, l = Math.min(prevInput.length, text.length);
         | 
| 737 | 
            -
                        while (same < l && prevInput[same] == text[same]) ++same;
         | 
| 738 | 
            -
                        if (same < prevInput.length)
         | 
| 739 | 
            -
                            sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};
         | 
| 740 | 
            -
                        else if (overwrite && posEq(sel.from, sel.to))
         | 
| 741 | 
            -
                            sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
         | 
| 742 | 
            -
                        replaceSelection(text.slice(same), "end");
         | 
| 743 | 
            -
                        prevInput = text;
         | 
| 744 | 
            -
                        return true;
         | 
| 745 | 
            -
                    }
         | 
| 746 | 
            -
                    function resetInput(user) {
         | 
| 747 | 
            -
                        if (!posEq(sel.from, sel.to)) {
         | 
| 748 | 
            -
                            prevInput = "";
         | 
| 749 | 
            -
                            input.value = getSelection();
         | 
| 750 | 
            -
                            input.select();
         | 
| 751 | 
            -
                        } else if (user) prevInput = input.value = "";
         | 
| 752 | 
            -
                    }
         | 
| 753 | 
            -
             | 
| 754 | 
            -
                    function focusInput() {
         | 
| 755 | 
            -
                        if (!options.readOnly) input.focus();
         | 
| 756 | 
            -
                    }
         | 
| 757 | 
            -
             | 
| 758 | 
            -
                    function scrollEditorIntoView() {
         | 
| 759 | 
            -
                        if (!cursor.getBoundingClientRect) return;
         | 
| 760 | 
            -
                        var rect = cursor.getBoundingClientRect();
         | 
| 761 | 
            -
                        // IE returns bogus coordinates when the instance sits inside of an iframe and the cursor is hidden
         | 
| 762 | 
            -
                        if (ie && rect.top == rect.bottom) return;
         | 
| 763 | 
            -
                        var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
         | 
| 764 | 
            -
                        if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
         | 
| 765 | 
            -
                    }
         | 
| 766 | 
            -
                    function scrollCursorIntoView() {
         | 
| 767 | 
            -
                        var cursor = localCoords(sel.inverted ? sel.from : sel.to);
         | 
| 768 | 
            -
                        var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
         | 
| 769 | 
            -
                        return scrollIntoView(x, cursor.y, x, cursor.yBot);
         | 
| 770 | 
            -
                    }
         | 
| 771 | 
            -
                    function scrollIntoView(x1, y1, x2, y2) {
         | 
| 772 | 
            -
                        var pl = paddingLeft(), pt = paddingTop(), lh = textHeight();
         | 
| 773 | 
            -
                        y1 += pt; y2 += pt; x1 += pl; x2 += pl;
         | 
| 774 | 
            -
                        var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
         | 
| 775 | 
            -
                        if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}
         | 
| 776 | 
            -
                        else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
         | 
| 777 | 
            -
             | 
| 778 | 
            -
                        var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
         | 
| 779 | 
            -
                        var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
         | 
| 780 | 
            -
                        if (x1 < screenleft + gutterw) {
         | 
| 781 | 
            -
                            if (x1 < 50) x1 = 0;
         | 
| 782 | 
            -
                            scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
         | 
| 783 | 
            -
                            scrolled = true;
         | 
| 784 | 
            -
                        }
         | 
| 785 | 
            -
                        else if (x2 > screenw + screenleft - 3) {
         | 
| 786 | 
            -
                            scroller.scrollLeft = x2 + 10 - screenw;
         | 
| 787 | 
            -
                            scrolled = true;
         | 
| 788 | 
            -
                            if (x2 > code.clientWidth) result = false;
         | 
| 789 | 
            -
                        }
         | 
| 790 | 
            -
                        if (scrolled && options.onScroll) options.onScroll(instance);
         | 
| 791 | 
            -
                        return result;
         | 
| 792 | 
            -
                    }
         | 
| 793 | 
            -
             | 
| 794 | 
            -
                    function visibleLines() {
         | 
| 795 | 
            -
                        var lh = textHeight(), top = scroller.scrollTop - paddingTop();
         | 
| 796 | 
            -
                        var from_height = Math.max(0, Math.floor(top / lh));
         | 
| 797 | 
            -
                        var to_height = Math.ceil((top + scroller.clientHeight) / lh);
         | 
| 798 | 
            -
                        return {from: lineAtHeight(doc, from_height),
         | 
| 799 | 
            -
                            to: lineAtHeight(doc, to_height)};
         | 
| 800 | 
            -
                    }
         | 
| 801 | 
            -
                    // Uses a set of changes plus the current scroll position to
         | 
| 802 | 
            -
                    // determine which DOM updates have to be made, and makes the
         | 
| 803 | 
            -
                    // updates.
         | 
| 804 | 
            -
                    function updateDisplay(changes, suppressCallback) {
         | 
| 805 | 
            -
                        if (!scroller.clientWidth) {
         | 
| 806 | 
            -
                            showingFrom = showingTo = displayOffset = 0;
         | 
| 807 | 
            -
                            return;
         | 
| 808 | 
            -
                        }
         | 
| 809 | 
            -
                        // Compute the new visible window
         | 
| 810 | 
            -
                        var visible = visibleLines();
         | 
| 811 | 
            -
                        // Bail out if the visible area is already rendered and nothing changed.
         | 
| 812 | 
            -
                        if (changes !== true && changes.length == 0 && visible.from >= showingFrom && visible.to <= showingTo) return;
         | 
| 813 | 
            -
                        var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
         | 
| 814 | 
            -
                        if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
         | 
| 815 | 
            -
                        if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
         | 
| 816 | 
            -
             | 
| 817 | 
            -
                        // Create a range of theoretically intact lines, and punch holes
         | 
| 818 | 
            -
                        // in that using the change info.
         | 
| 819 | 
            -
                        var intact = changes === true ? [] :
         | 
| 820 | 
            -
                            computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);
         | 
| 821 | 
            -
                        // Clip off the parts that won't be visible
         | 
| 822 | 
            -
                        var intactLines = 0;
         | 
| 823 | 
            -
                        for (var i = 0; i < intact.length; ++i) {
         | 
| 824 | 
            -
                            var range = intact[i];
         | 
| 825 | 
            -
                            if (range.from < from) {range.domStart += (from - range.from); range.from = from;}
         | 
| 826 | 
            -
                            if (range.to > to) range.to = to;
         | 
| 827 | 
            -
                            if (range.from >= range.to) intact.splice(i--, 1);
         | 
| 828 | 
            -
                            else intactLines += range.to - range.from;
         | 
| 829 | 
            -
                        }
         | 
| 830 | 
            -
                        if (intactLines == to - from) return;
         | 
| 831 | 
            -
                        intact.sort(function(a, b) {return a.domStart - b.domStart;});
         | 
| 832 | 
            -
             | 
| 833 | 
            -
                        var th = textHeight(), gutterDisplay = gutter.style.display;
         | 
| 834 | 
            -
                        lineDiv.style.display = gutter.style.display = "none";
         | 
| 835 | 
            -
                        patchDisplay(from, to, intact);
         | 
| 836 | 
            -
                        lineDiv.style.display = "";
         | 
| 837 | 
            -
             | 
| 838 | 
            -
                        // Position the mover div to align with the lines it's supposed
         | 
| 839 | 
            -
                        // to be showing (which will cover the visible display)
         | 
| 840 | 
            -
                        var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;
         | 
| 841 | 
            -
                        // This is just a bogus formula that detects when the editor is
         | 
| 842 | 
            -
                        // resized or the font size changes.
         | 
| 843 | 
            -
                        if (different) lastSizeC = scroller.clientHeight + th;
         | 
| 844 | 
            -
                        showingFrom = from; showingTo = to;
         | 
| 845 | 
            -
                        displayOffset = heightAtLine(doc, from);
         | 
| 846 | 
            -
                        mover.style.top = (displayOffset * th) + "px";
         | 
| 847 | 
            -
                        code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
         | 
| 848 | 
            -
             | 
| 849 | 
            -
                        // Since this is all rather error prone, it is honoured with the
         | 
| 850 | 
            -
                        // only assertion in the whole file.
         | 
| 851 | 
            -
                        if (lineDiv.childNodes.length != showingTo - showingFrom)
         | 
| 852 | 
            -
                            throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
         | 
| 853 | 
            -
                                " nodes=" + lineDiv.childNodes.length);
         | 
| 854 | 
            -
             | 
| 855 | 
            -
                        if (options.lineWrapping) {
         | 
| 856 | 
            -
                            maxWidth = scroller.clientWidth;
         | 
| 857 | 
            -
                            var curNode = lineDiv.firstChild;
         | 
| 858 | 
            -
                            doc.iter(showingFrom, showingTo, function(line) {
         | 
| 859 | 
            -
                                if (!line.hidden) {
         | 
| 860 | 
            -
                                    var height = Math.round(curNode.offsetHeight / th) || 1;
         | 
| 861 | 
            -
                                    if (line.height != height) {updateLineHeight(line, height); gutterDirty = true;}
         | 
| 862 | 
            -
                                }
         | 
| 863 | 
            -
                                curNode = curNode.nextSibling;
         | 
| 864 | 
            -
                            });
         | 
| 865 | 
            -
                        } else {
         | 
| 866 | 
            -
                            if (maxWidth == null) maxWidth = stringWidth(maxLine);
         | 
| 867 | 
            -
                            if (maxWidth > scroller.clientWidth) {
         | 
| 868 | 
            -
                                lineSpace.style.width = maxWidth + "px";
         | 
| 869 | 
            -
                                // Needed to prevent odd wrapping/hiding of widgets placed in here.
         | 
| 870 | 
            -
                                code.style.width = "";
         | 
| 871 | 
            -
                                code.style.width = scroller.scrollWidth + "px";
         | 
| 872 | 
            -
                            } else {
         | 
| 873 | 
            -
                                lineSpace.style.width = code.style.width = "";
         | 
| 874 | 
            -
                            }
         | 
| 875 | 
            -
                        }
         | 
| 876 | 
            -
                        gutter.style.display = gutterDisplay;
         | 
| 877 | 
            -
                        if (different || gutterDirty) updateGutter();
         | 
| 878 | 
            -
                        updateCursor();
         | 
| 879 | 
            -
                        if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
         | 
| 880 | 
            -
                        return true;
         | 
| 881 | 
            -
                    }
         | 
| 882 | 
            -
             | 
| 883 | 
            -
                    function computeIntact(intact, changes) {
         | 
| 884 | 
            -
                        for (var i = 0, l = changes.length || 0; i < l; ++i) {
         | 
| 885 | 
            -
                            var change = changes[i], intact2 = [], diff = change.diff || 0;
         | 
| 886 | 
            -
                            for (var j = 0, l2 = intact.length; j < l2; ++j) {
         | 
| 887 | 
            -
                                var range = intact[j];
         | 
| 888 | 
            -
                                if (change.to <= range.from && change.diff)
         | 
| 889 | 
            -
                                    intact2.push({from: range.from + diff, to: range.to + diff,
         | 
| 890 | 
            -
                                        domStart: range.domStart});
         | 
| 891 | 
            -
                                else if (change.to <= range.from || change.from >= range.to)
         | 
| 892 | 
            -
                                    intact2.push(range);
         | 
| 893 | 
            -
                                else {
         | 
| 894 | 
            -
                                    if (change.from > range.from)
         | 
| 895 | 
            -
                                        intact2.push({from: range.from, to: change.from, domStart: range.domStart});
         | 
| 896 | 
            -
                                    if (change.to < range.to)
         | 
| 897 | 
            -
                                        intact2.push({from: change.to + diff, to: range.to + diff,
         | 
| 898 | 
            -
                                            domStart: range.domStart + (change.to - range.from)});
         | 
| 899 | 
            -
                                }
         | 
| 900 | 
            -
                            }
         | 
| 901 | 
            -
                            intact = intact2;
         | 
| 902 | 
            -
                        }
         | 
| 903 | 
            -
                        return intact;
         | 
| 904 | 
            -
                    }
         | 
| 905 | 
            -
             | 
| 906 | 
            -
                    function patchDisplay(from, to, intact) {
         | 
| 907 | 
            -
                        // The first pass removes the DOM nodes that aren't intact.
         | 
| 908 | 
            -
                        if (!intact.length) lineDiv.innerHTML = "";
         | 
| 909 | 
            -
                        else {
         | 
| 910 | 
            -
                            function killNode(node) {
         | 
| 911 | 
            -
                                var tmp = node.nextSibling;
         | 
| 912 | 
            -
                                node.parentNode.removeChild(node);
         | 
| 913 | 
            -
                                return tmp;
         | 
| 914 | 
            -
                            }
         | 
| 915 | 
            -
                            var domPos = 0, curNode = lineDiv.firstChild, n;
         | 
| 916 | 
            -
                            for (var i = 0; i < intact.length; ++i) {
         | 
| 917 | 
            -
                                var cur = intact[i];
         | 
| 918 | 
            -
                                while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}
         | 
| 919 | 
            -
                                for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}
         | 
| 920 | 
            -
                            }
         | 
| 921 | 
            -
                            while (curNode) curNode = killNode(curNode);
         | 
| 922 | 
            -
                        }
         | 
| 923 | 
            -
                        // This pass fills in the lines that actually changed.
         | 
| 924 | 
            -
                        var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
         | 
| 925 | 
            -
                        var sfrom = sel.from.line, sto = sel.to.line, inSel = sfrom < from && sto >= from;
         | 
| 926 | 
            -
                        var scratch = targetDocument.createElement("div"), newElt;
         | 
| 927 | 
            -
                        doc.iter(from, to, function(line) {
         | 
| 928 | 
            -
                            var ch1 = null, ch2 = null;
         | 
| 929 | 
            -
                            if (inSel) {
         | 
| 930 | 
            -
                                ch1 = 0;
         | 
| 931 | 
            -
                                if (sto == j) {inSel = false; ch2 = sel.to.ch;}
         | 
| 932 | 
            -
                            } else if (sfrom == j) {
         | 
| 933 | 
            -
                                if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
         | 
| 934 | 
            -
                                else {inSel = true; ch1 = sel.from.ch;}
         | 
| 935 | 
            -
                            }
         | 
| 936 | 
            -
                            if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
         | 
| 937 | 
            -
                            if (!nextIntact || nextIntact.from > j) {
         | 
| 938 | 
            -
                                if (line.hidden) scratch.innerHTML = "<pre></pre>";
         | 
| 939 | 
            -
                                else scratch.innerHTML = line.getHTML(ch1, ch2, true, tabText);
         | 
| 940 | 
            -
                                lineDiv.insertBefore(scratch.firstChild, curNode);
         | 
| 941 | 
            -
                            } else {
         | 
| 942 | 
            -
                                curNode = curNode.nextSibling;
         | 
| 943 | 
            -
                            }
         | 
| 944 | 
            -
                            ++j;
         | 
| 945 | 
            -
                        });
         | 
| 946 | 
            -
                    }
         | 
| 947 | 
            -
             | 
| 948 | 
            -
                    function updateGutter() {
         | 
| 949 | 
            -
                        if (!options.gutter && !options.lineNumbers) return;
         | 
| 950 | 
            -
                        var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
         | 
| 951 | 
            -
                        gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
         | 
| 952 | 
            -
                        var html = [], i = showingFrom;
         | 
| 953 | 
            -
                        doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
         | 
| 954 | 
            -
                            if (line.hidden) {
         | 
| 955 | 
            -
                                html.push("<pre></pre>");
         | 
| 956 | 
            -
                            } else {
         | 
| 957 | 
            -
                                var marker = line.gutterMarker;
         | 
| 958 | 
            -
                                var text = options.lineNumbers ? i + options.firstLineNumber : null;
         | 
| 959 | 
            -
                                if (marker && marker.text)
         | 
| 960 | 
            -
                                    text = marker.text.replace("%N%", text != null ? text : "");
         | 
| 961 | 
            -
                                else if (text == null)
         | 
| 962 | 
            -
                                    text = "\u00a0";
         | 
| 963 | 
            -
                                html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text);
         | 
| 964 | 
            -
                                for (var j = 1; j < line.height; ++j) html.push("<br/> ");
         | 
| 965 | 
            -
                                html.push("</pre>");
         | 
| 966 | 
            -
                            }
         | 
| 967 | 
            -
                            ++i;
         | 
| 968 | 
            -
                        });
         | 
| 969 | 
            -
                        gutter.style.display = "none";
         | 
| 970 | 
            -
                        gutterText.innerHTML = html.join("");
         | 
| 971 | 
            -
                        var minwidth = String(doc.size).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
         | 
| 972 | 
            -
                        while (val.length + pad.length < minwidth) pad += "\u00a0";
         | 
| 973 | 
            -
                        if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
         | 
| 974 | 
            -
                        gutter.style.display = "";
         | 
| 975 | 
            -
                        lineSpace.style.marginLeft = gutter.offsetWidth + "px";
         | 
| 976 | 
            -
                        gutterDirty = false;
         | 
| 977 | 
            -
                    }
         | 
| 978 | 
            -
                    function updateCursor() {
         | 
| 979 | 
            -
                        var head = sel.inverted ? sel.from : sel.to, lh = textHeight();
         | 
| 980 | 
            -
                        var pos = localCoords(head, true);
         | 
| 981 | 
            -
                        var wrapOff = eltOffset(wrapper), lineOff = eltOffset(lineDiv);
         | 
| 982 | 
            -
                        inputDiv.style.top = (pos.y + lineOff.top - wrapOff.top) + "px";
         | 
| 983 | 
            -
                        inputDiv.style.left = (pos.x + lineOff.left - wrapOff.left) + "px";
         | 
| 984 | 
            -
                        if (posEq(sel.from, sel.to)) {
         | 
| 985 | 
            -
                            cursor.style.top = pos.y + "px";
         | 
| 986 | 
            -
                            cursor.style.left = (options.lineWrapping ? Math.min(pos.x, lineSpace.offsetWidth) : pos.x) + "px";
         | 
| 987 | 
            -
                            cursor.style.display = "";
         | 
| 988 | 
            -
                        }
         | 
| 989 | 
            -
                        else cursor.style.display = "none";
         | 
| 990 | 
            -
                    }
         | 
| 991 | 
            -
             | 
| 992 | 
            -
                    function setShift(val) {
         | 
| 993 | 
            -
                        if (val) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);
         | 
| 994 | 
            -
                        else shiftSelecting = null;
         | 
| 995 | 
            -
                    }
         | 
| 996 | 
            -
                    function setSelectionUser(from, to) {
         | 
| 997 | 
            -
                        var sh = shiftSelecting && clipPos(shiftSelecting);
         | 
| 998 | 
            -
                        if (sh) {
         | 
| 999 | 
            -
                            if (posLess(sh, from)) from = sh;
         | 
| 1000 | 
            -
                            else if (posLess(to, sh)) to = sh;
         | 
| 1001 | 
            -
                        }
         | 
| 1002 | 
            -
                        setSelection(from, to);
         | 
| 1003 | 
            -
                        userSelChange = true;
         | 
| 1004 | 
            -
                    }
         | 
| 1005 | 
            -
                    // Update the selection. Last two args are only used by
         | 
| 1006 | 
            -
                    // updateLines, since they have to be expressed in the line
         | 
| 1007 | 
            -
                    // numbers before the update.
         | 
| 1008 | 
            -
                    function setSelection(from, to, oldFrom, oldTo) {
         | 
| 1009 | 
            -
                        goalColumn = null;
         | 
| 1010 | 
            -
                        if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
         | 
| 1011 | 
            -
                        if (posEq(sel.from, from) && posEq(sel.to, to)) return;
         | 
| 1012 | 
            -
                        if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
         | 
| 1013 | 
            -
             | 
| 1014 | 
            -
                        // Skip over hidden lines.
         | 
| 1015 | 
            -
                        if (from.line != oldFrom) from = skipHidden(from, oldFrom, sel.from.ch);
         | 
| 1016 | 
            -
                        if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
         | 
| 1017 | 
            -
             | 
| 1018 | 
            -
                        if (posEq(from, to)) sel.inverted = false;
         | 
| 1019 | 
            -
                        else if (posEq(from, sel.to)) sel.inverted = false;
         | 
| 1020 | 
            -
                        else if (posEq(to, sel.from)) sel.inverted = true;
         | 
| 1021 | 
            -
             | 
| 1022 | 
            -
                        // Some ugly logic used to only mark the lines that actually did
         | 
| 1023 | 
            -
                        // see a change in selection as changed, rather than the whole
         | 
| 1024 | 
            -
                        // selected range.
         | 
| 1025 | 
            -
                        if (posEq(from, to)) {
         | 
| 1026 | 
            -
                            if (!posEq(sel.from, sel.to))
         | 
| 1027 | 
            -
                                changes.push({from: oldFrom, to: oldTo + 1});
         | 
| 1028 | 
            -
                        }
         | 
| 1029 | 
            -
                        else if (posEq(sel.from, sel.to)) {
         | 
| 1030 | 
            -
                            changes.push({from: from.line, to: to.line + 1});
         | 
| 1031 | 
            -
                        }
         | 
| 1032 | 
            -
                        else {
         | 
| 1033 | 
            -
                            if (!posEq(from, sel.from)) {
         | 
| 1034 | 
            -
                                if (from.line < oldFrom)
         | 
| 1035 | 
            -
                                    changes.push({from: from.line, to: Math.min(to.line, oldFrom) + 1});
         | 
| 1036 | 
            -
                                else
         | 
| 1037 | 
            -
                                    changes.push({from: oldFrom, to: Math.min(oldTo, from.line) + 1});
         | 
| 1038 | 
            -
                            }
         | 
| 1039 | 
            -
                            if (!posEq(to, sel.to)) {
         | 
| 1040 | 
            -
                                if (to.line < oldTo)
         | 
| 1041 | 
            -
                                    changes.push({from: Math.max(oldFrom, from.line), to: oldTo + 1});
         | 
| 1042 | 
            -
                                else
         | 
| 1043 | 
            -
                                    changes.push({from: Math.max(from.line, oldTo), to: to.line + 1});
         | 
| 1044 | 
            -
                            }
         | 
| 1045 | 
            -
                        }
         | 
| 1046 | 
            -
                        sel.from = from; sel.to = to;
         | 
| 1047 | 
            -
                        selectionChanged = true;
         | 
| 1048 | 
            -
                    }
         | 
| 1049 | 
            -
                    function skipHidden(pos, oldLine, oldCh) {
         | 
| 1050 | 
            -
                        function getNonHidden(dir) {
         | 
| 1051 | 
            -
                            var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;
         | 
| 1052 | 
            -
                            while (lNo != end) {
         | 
| 1053 | 
            -
                                var line = getLine(lNo);
         | 
| 1054 | 
            -
                                if (!line.hidden) {
         | 
| 1055 | 
            -
                                    var ch = pos.ch;
         | 
| 1056 | 
            -
                                    if (ch > oldCh || ch > line.text.length) ch = line.text.length;
         | 
| 1057 | 
            -
                                    return {line: lNo, ch: ch};
         | 
| 1058 | 
            -
                                }
         | 
| 1059 | 
            -
                                lNo += dir;
         | 
| 1060 | 
            -
                            }
         | 
| 1061 | 
            -
                        }
         | 
| 1062 | 
            -
                        var line = getLine(pos.line);
         | 
| 1063 | 
            -
                        if (!line.hidden) return pos;
         | 
| 1064 | 
            -
                        if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
         | 
| 1065 | 
            -
                        else return getNonHidden(-1) || getNonHidden(1);
         | 
| 1066 | 
            -
                    }
         | 
| 1067 | 
            -
                    function setCursor(line, ch, user) {
         | 
| 1068 | 
            -
                        var pos = clipPos({line: line, ch: ch || 0});
         | 
| 1069 | 
            -
                        (user ? setSelectionUser : setSelection)(pos, pos);
         | 
| 1070 | 
            -
                    }
         | 
| 1071 | 
            -
             | 
| 1072 | 
            -
                    function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}
         | 
| 1073 | 
            -
                    function clipPos(pos) {
         | 
| 1074 | 
            -
                        if (pos.line < 0) return {line: 0, ch: 0};
         | 
| 1075 | 
            -
                        if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};
         | 
| 1076 | 
            -
                        var ch = pos.ch, linelen = getLine(pos.line).text.length;
         | 
| 1077 | 
            -
                        if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
         | 
| 1078 | 
            -
                        else if (ch < 0) return {line: pos.line, ch: 0};
         | 
| 1079 | 
            -
                        else return pos;
         | 
| 1080 | 
            -
                    }
         | 
| 1081 | 
            -
             | 
| 1082 | 
            -
                    function findPosH(dir, unit) {
         | 
| 1083 | 
            -
                        var end = sel.inverted ? sel.from : sel.to, line = end.line, ch = end.ch;
         | 
| 1084 | 
            -
                        var lineObj = getLine(line);
         | 
| 1085 | 
            -
                        function findNextLine() {
         | 
| 1086 | 
            -
                            for (var l = line + dir, e = dir < 0 ? -1 : doc.size; l != e; l += dir) {
         | 
| 1087 | 
            -
                                var lo = getLine(l);
         | 
| 1088 | 
            -
                                if (!lo.hidden) { line = l; lineObj = lo; return true; }
         | 
| 1089 | 
            -
                            }
         | 
| 1090 | 
            -
                        }
         | 
| 1091 | 
            -
                        function moveOnce(boundToLine) {
         | 
| 1092 | 
            -
                            if (ch == (dir < 0 ? 0 : lineObj.text.length)) {
         | 
| 1093 | 
            -
                                if (!boundToLine && findNextLine()) ch = dir < 0 ? lineObj.text.length : 0;
         | 
| 1094 | 
            -
                                else return false;
         | 
| 1095 | 
            -
                            } else ch += dir;
         | 
| 1096 | 
            -
                            return true;
         | 
| 1097 | 
            -
                        }
         | 
| 1098 | 
            -
                        if (unit == "char") moveOnce();
         | 
| 1099 | 
            -
                        else if (unit == "column") moveOnce(true);
         | 
| 1100 | 
            -
                        else if (unit == "word") {
         | 
| 1101 | 
            -
                            var sawWord = false;
         | 
| 1102 | 
            -
                            for (;;) {
         | 
| 1103 | 
            -
                                if (dir < 0) if (!moveOnce()) break;
         | 
| 1104 | 
            -
                                if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;
         | 
| 1105 | 
            -
                                else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}
         | 
| 1106 | 
            -
                                if (dir > 0) if (!moveOnce()) break;
         | 
| 1107 | 
            -
                            }
         | 
| 1108 | 
            -
                        }
         | 
| 1109 | 
            -
                        return {line: line, ch: ch};
         | 
| 1110 | 
            -
                    }
         | 
| 1111 | 
            -
                    function moveH(dir, unit) {
         | 
| 1112 | 
            -
                        var pos = dir < 0 ? sel.from : sel.to;
         | 
| 1113 | 
            -
                        if (shiftSelecting || posEq(sel.from, sel.to)) pos = findPosH(dir, unit);
         | 
| 1114 | 
            -
                        setCursor(pos.line, pos.ch, true);
         | 
| 1115 | 
            -
                    }
         | 
| 1116 | 
            -
                    function deleteH(dir, unit) {
         | 
| 1117 | 
            -
                        if (!posEq(sel.from, sel.to)) replaceRange("", sel.from, sel.to);
         | 
| 1118 | 
            -
                        else if (dir < 0) replaceRange("", findPosH(dir, unit), sel.to);
         | 
| 1119 | 
            -
                        else replaceRange("", sel.from, findPosH(dir, unit));
         | 
| 1120 | 
            -
                        userSelChange = true;
         | 
| 1121 | 
            -
                    }
         | 
| 1122 | 
            -
                    var goalColumn = null;
         | 
| 1123 | 
            -
                    function moveV(dir, unit) {
         | 
| 1124 | 
            -
                        var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);
         | 
| 1125 | 
            -
                        if (goalColumn != null) pos.x = goalColumn;
         | 
| 1126 | 
            -
                        if (unit == "page") dist = scroller.clientHeight;
         | 
| 1127 | 
            -
                        else if (unit == "line") dist = textHeight();
         | 
| 1128 | 
            -
                        var target = coordsChar(pos.x, pos.y + dist * dir + 2);
         | 
| 1129 | 
            -
                        setCursor(target.line, target.ch, true);
         | 
| 1130 | 
            -
                        goalColumn = pos.x;
         | 
| 1131 | 
            -
                    }
         | 
| 1132 | 
            -
             | 
| 1133 | 
            -
                    function selectWordAt(pos) {
         | 
| 1134 | 
            -
                        var line = getLine(pos.line).text;
         | 
| 1135 | 
            -
                        var start = pos.ch, end = pos.ch;
         | 
| 1136 | 
            -
                        while (start > 0 && isWordChar(line.charAt(start - 1))) --start;
         | 
| 1137 | 
            -
                        while (end < line.length && isWordChar(line.charAt(end))) ++end;
         | 
| 1138 | 
            -
                        setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});
         | 
| 1139 | 
            -
                    }
         | 
| 1140 | 
            -
                    function selectLine(line) {
         | 
| 1141 | 
            -
                        setSelectionUser({line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
         | 
| 1142 | 
            -
                    }
         | 
| 1143 | 
            -
                    function indentSelected(mode) {
         | 
| 1144 | 
            -
                        if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
         | 
| 1145 | 
            -
                        var e = sel.to.line - (sel.to.ch ? 0 : 1);
         | 
| 1146 | 
            -
                        for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);
         | 
| 1147 | 
            -
                    }
         | 
| 1148 | 
            -
             | 
| 1149 | 
            -
                    function indentLine(n, how) {
         | 
| 1150 | 
            -
                        if (!how) how = "add";
         | 
| 1151 | 
            -
                        if (how == "smart") {
         | 
| 1152 | 
            -
                            if (!mode.indent) how = "prev";
         | 
| 1153 | 
            -
                            else var state = getStateBefore(n);
         | 
| 1154 | 
            -
                        }
         | 
| 1155 | 
            -
             | 
| 1156 | 
            -
                        var line = getLine(n), curSpace = line.indentation(options.tabSize),
         | 
| 1157 | 
            -
                            curSpaceString = line.text.match(/^\s*/)[0], indentation;
         | 
| 1158 | 
            -
                        if (how == "prev") {
         | 
| 1159 | 
            -
                            if (n) indentation = getLine(n-1).indentation(options.tabSize);
         | 
| 1160 | 
            -
                            else indentation = 0;
         | 
| 1161 | 
            -
                        }
         | 
| 1162 | 
            -
                        else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
         | 
| 1163 | 
            -
                        else if (how == "add") indentation = curSpace + options.indentUnit;
         | 
| 1164 | 
            -
                        else if (how == "subtract") indentation = curSpace - options.indentUnit;
         | 
| 1165 | 
            -
                        indentation = Math.max(0, indentation);
         | 
| 1166 | 
            -
                        var diff = indentation - curSpace;
         | 
| 1167 | 
            -
             | 
| 1168 | 
            -
                        if (!diff) {
         | 
| 1169 | 
            -
                            if (sel.from.line != n && sel.to.line != n) return;
         | 
| 1170 | 
            -
                            var indentString = curSpaceString;
         | 
| 1171 | 
            -
                        }
         | 
| 1172 | 
            -
                        else {
         | 
| 1173 | 
            -
                            var indentString = "", pos = 0;
         | 
| 1174 | 
            -
                            if (options.indentWithTabs)
         | 
| 1175 | 
            -
                                for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
         | 
| 1176 | 
            -
                            while (pos < indentation) {++pos; indentString += " ";}
         | 
| 1177 | 
            -
                        }
         | 
| 1178 | 
            -
             | 
| 1179 | 
            -
                        replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
         | 
| 1180 | 
            -
                    }
         | 
| 1181 | 
            -
             | 
| 1182 | 
            -
                    function loadMode() {
         | 
| 1183 | 
            -
                        mode = CodeMirror.getMode(options, options.mode);
         | 
| 1184 | 
            -
                        doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
         | 
| 1185 | 
            -
                        work = [0];
         | 
| 1186 | 
            -
                        startWorker();
         | 
| 1187 | 
            -
                    }
         | 
| 1188 | 
            -
                    function gutterChanged() {
         | 
| 1189 | 
            -
                        var visible = options.gutter || options.lineNumbers;
         | 
| 1190 | 
            -
                        gutter.style.display = visible ? "" : "none";
         | 
| 1191 | 
            -
                        if (visible) gutterDirty = true;
         | 
| 1192 | 
            -
                        else lineDiv.parentNode.style.marginLeft = 0;
         | 
| 1193 | 
            -
                    }
         | 
| 1194 | 
            -
                    function wrappingChanged(from, to) {
         | 
| 1195 | 
            -
                        if (options.lineWrapping) {
         | 
| 1196 | 
            -
                            wrapper.className += " CodeMirror-wrap";
         | 
| 1197 | 
            -
                            var perLine = scroller.clientWidth / charWidth() - 3;
         | 
| 1198 | 
            -
                            doc.iter(0, doc.size, function(line) {
         | 
| 1199 | 
            -
                                if (line.hidden) return;
         | 
| 1200 | 
            -
                                var guess = Math.ceil(line.text.length / perLine) || 1;
         | 
| 1201 | 
            -
                                if (guess != 1) updateLineHeight(line, guess);
         | 
| 1202 | 
            -
                            });
         | 
| 1203 | 
            -
                            lineSpace.style.width = code.style.width = "";
         | 
| 1204 | 
            -
                        } else {
         | 
| 1205 | 
            -
                            wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
         | 
| 1206 | 
            -
                            maxWidth = null; maxLine = "";
         | 
| 1207 | 
            -
                            doc.iter(0, doc.size, function(line) {
         | 
| 1208 | 
            -
                                if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
         | 
| 1209 | 
            -
                                if (line.text.length > maxLine.length) maxLine = line.text;
         | 
| 1210 | 
            -
                            });
         | 
| 1211 | 
            -
                        }
         | 
| 1212 | 
            -
                        changes.push({from: 0, to: doc.size});
         | 
| 1213 | 
            -
                    }
         | 
| 1214 | 
            -
                    function computeTabText() {
         | 
| 1215 | 
            -
                        for (var str = '<span class="cm-tab">', i = 0; i < options.tabSize; ++i) str += " ";
         | 
| 1216 | 
            -
                        return str + "</span>";
         | 
| 1217 | 
            -
                    }
         | 
| 1218 | 
            -
                    function tabsChanged() {
         | 
| 1219 | 
            -
                        tabText = computeTabText();
         | 
| 1220 | 
            -
                        updateDisplay(true);
         | 
| 1221 | 
            -
                    }
         | 
| 1222 | 
            -
                    function themeChanged() {
         | 
| 1223 | 
            -
                        scroller.className = scroller.className.replace(/\s*cm-s-\w+/g, "") +
         | 
| 1224 | 
            -
                            options.theme.replace(/(^|\s)\s*/g, " cm-s-");
         | 
| 1225 | 
            -
                    }
         | 
| 1226 | 
            -
             | 
| 1227 | 
            -
                    function TextMarker() { this.set = []; }
         | 
| 1228 | 
            -
                    TextMarker.prototype.clear = operation(function() {
         | 
| 1229 | 
            -
                        var min = Infinity, max = -Infinity;
         | 
| 1230 | 
            -
                        for (var i = 0, e = this.set.length; i < e; ++i) {
         | 
| 1231 | 
            -
                            var line = this.set[i], mk = line.marked;
         | 
| 1232 | 
            -
                            if (!mk || !line.parent) continue;
         | 
| 1233 | 
            -
                            var lineN = lineNo(line);
         | 
| 1234 | 
            -
                            min = Math.min(min, lineN); max = Math.max(max, lineN);
         | 
| 1235 | 
            -
                            for (var j = 0; j < mk.length; ++j)
         | 
| 1236 | 
            -
                                if (mk[j].set == this.set) mk.splice(j--, 1);
         | 
| 1237 | 
            -
                        }
         | 
| 1238 | 
            -
                        if (min != Infinity)
         | 
| 1239 | 
            -
                            changes.push({from: min, to: max + 1});
         | 
| 1240 | 
            -
                    });
         | 
| 1241 | 
            -
                    TextMarker.prototype.find = function() {
         | 
| 1242 | 
            -
                        var from, to;
         | 
| 1243 | 
            -
                        for (var i = 0, e = this.set.length; i < e; ++i) {
         | 
| 1244 | 
            -
                            var line = this.set[i], mk = line.marked;
         | 
| 1245 | 
            -
                            for (var j = 0; j < mk.length; ++j) {
         | 
| 1246 | 
            -
                                var mark = mk[j];
         | 
| 1247 | 
            -
                                if (mark.set == this.set) {
         | 
| 1248 | 
            -
                                    if (mark.from != null || mark.to != null) {
         | 
| 1249 | 
            -
                                        var found = lineNo(line);
         | 
| 1250 | 
            -
                                        if (found != null) {
         | 
| 1251 | 
            -
                                            if (mark.from != null) from = {line: found, ch: mark.from};
         | 
| 1252 | 
            -
                                            if (mark.to != null) to = {line: found, ch: mark.to};
         | 
| 1253 | 
            -
                                        }
         | 
| 1254 | 
            -
                                    }
         | 
| 1255 | 
            -
                                }
         | 
| 1256 | 
            -
                            }
         | 
| 1257 | 
            -
                        }
         | 
| 1258 | 
            -
                        return {from: from, to: to};
         | 
| 1259 | 
            -
                    };
         | 
| 1260 | 
            -
             | 
| 1261 | 
            -
                    function markText(from, to, className) {
         | 
| 1262 | 
            -
                        from = clipPos(from); to = clipPos(to);
         | 
| 1263 | 
            -
                        var tm = new TextMarker();
         | 
| 1264 | 
            -
                        function add(line, from, to, className) {
         | 
| 1265 | 
            -
                            getLine(line).addMark(new MarkedText(from, to, className, tm.set));
         | 
| 1266 | 
            -
                        }
         | 
| 1267 | 
            -
                        if (from.line == to.line) add(from.line, from.ch, to.ch, className);
         | 
| 1268 | 
            -
                        else {
         | 
| 1269 | 
            -
                            add(from.line, from.ch, null, className);
         | 
| 1270 | 
            -
                            for (var i = from.line + 1, e = to.line; i < e; ++i)
         | 
| 1271 | 
            -
                                add(i, null, null, className);
         | 
| 1272 | 
            -
                            add(to.line, null, to.ch, className);
         | 
| 1273 | 
            -
                        }
         | 
| 1274 | 
            -
                        changes.push({from: from.line, to: to.line + 1});
         | 
| 1275 | 
            -
                        return tm;
         | 
| 1276 | 
            -
                    }
         | 
| 1277 | 
            -
             | 
| 1278 | 
            -
                    function setBookmark(pos) {
         | 
| 1279 | 
            -
                        pos = clipPos(pos);
         | 
| 1280 | 
            -
                        var bm = new Bookmark(pos.ch);
         | 
| 1281 | 
            -
                        getLine(pos.line).addMark(bm);
         | 
| 1282 | 
            -
                        return bm;
         | 
| 1283 | 
            -
                    }
         | 
| 1284 | 
            -
             | 
| 1285 | 
            -
                    function addGutterMarker(line, text, className) {
         | 
| 1286 | 
            -
                        if (typeof line == "number") line = getLine(clipLine(line));
         | 
| 1287 | 
            -
                        line.gutterMarker = {text: text, style: className};
         | 
| 1288 | 
            -
                        gutterDirty = true;
         | 
| 1289 | 
            -
                        return line;
         | 
| 1290 | 
            -
                    }
         | 
| 1291 | 
            -
                    function removeGutterMarker(line) {
         | 
| 1292 | 
            -
                        if (typeof line == "number") line = getLine(clipLine(line));
         | 
| 1293 | 
            -
                        line.gutterMarker = null;
         | 
| 1294 | 
            -
                        gutterDirty = true;
         | 
| 1295 | 
            -
                    }
         | 
| 1296 | 
            -
             | 
| 1297 | 
            -
                    function changeLine(handle, op) {
         | 
| 1298 | 
            -
                        var no = handle, line = handle;
         | 
| 1299 | 
            -
                        if (typeof handle == "number") line = getLine(clipLine(handle));
         | 
| 1300 | 
            -
                        else no = lineNo(handle);
         | 
| 1301 | 
            -
                        if (no == null) return null;
         | 
| 1302 | 
            -
                        if (op(line, no)) changes.push({from: no, to: no + 1});
         | 
| 1303 | 
            -
                        else return null;
         | 
| 1304 | 
            -
                        return line;
         | 
| 1305 | 
            -
                    }
         | 
| 1306 | 
            -
                    function setLineClass(handle, className) {
         | 
| 1307 | 
            -
                        return changeLine(handle, function(line) {
         | 
| 1308 | 
            -
                            if (line.className != className) {
         | 
| 1309 | 
            -
                                line.className = className;
         | 
| 1310 | 
            -
                                return true;
         | 
| 1311 | 
            -
                            }
         | 
| 1312 | 
            -
                        });
         | 
| 1313 | 
            -
                    }
         | 
| 1314 | 
            -
                    function setLineHidden(handle, hidden) {
         | 
| 1315 | 
            -
                        return changeLine(handle, function(line, no) {
         | 
| 1316 | 
            -
                            if (line.hidden != hidden) {
         | 
| 1317 | 
            -
                                line.hidden = hidden;
         | 
| 1318 | 
            -
                                updateLineHeight(line, hidden ? 0 : 1);
         | 
| 1319 | 
            -
                                if (hidden && (sel.from.line == no || sel.to.line == no))
         | 
| 1320 | 
            -
                                    setSelection(skipHidden(sel.from, sel.from.line, sel.from.ch),
         | 
| 1321 | 
            -
                                        skipHidden(sel.to, sel.to.line, sel.to.ch));
         | 
| 1322 | 
            -
                                return (gutterDirty = true);
         | 
| 1323 | 
            -
                            }
         | 
| 1324 | 
            -
                        });
         | 
| 1325 | 
            -
                    }
         | 
| 1326 | 
            -
             | 
| 1327 | 
            -
                    function lineInfo(line) {
         | 
| 1328 | 
            -
                        if (typeof line == "number") {
         | 
| 1329 | 
            -
                            if (!isLine(line)) return null;
         | 
| 1330 | 
            -
                            var n = line;
         | 
| 1331 | 
            -
                            line = getLine(line);
         | 
| 1332 | 
            -
                            if (!line) return null;
         | 
| 1333 | 
            -
                        }
         | 
| 1334 | 
            -
                        else {
         | 
| 1335 | 
            -
                            var n = lineNo(line);
         | 
| 1336 | 
            -
                            if (n == null) return null;
         | 
| 1337 | 
            -
                        }
         | 
| 1338 | 
            -
                        var marker = line.gutterMarker;
         | 
| 1339 | 
            -
                        return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
         | 
| 1340 | 
            -
                            markerClass: marker && marker.style, lineClass: line.className};
         | 
| 1341 | 
            -
                    }
         | 
| 1342 | 
            -
             | 
| 1343 | 
            -
                    function stringWidth(str) {
         | 
| 1344 | 
            -
                        measure.innerHTML = "<pre><span>x</span></pre>";
         | 
| 1345 | 
            -
                        measure.firstChild.firstChild.firstChild.nodeValue = str;
         | 
| 1346 | 
            -
                        return measure.firstChild.firstChild.offsetWidth || 10;
         | 
| 1347 | 
            -
                    }
         | 
| 1348 | 
            -
                    // These are used to go from pixel positions to character
         | 
| 1349 | 
            -
                    // positions, taking varying character widths into account.
         | 
| 1350 | 
            -
                    function charFromX(line, x) {
         | 
| 1351 | 
            -
                        if (x <= 0) return 0;
         | 
| 1352 | 
            -
                        var lineObj = getLine(line), text = lineObj.text;
         | 
| 1353 | 
            -
                        function getX(len) {
         | 
| 1354 | 
            -
                            measure.innerHTML = "<pre><span>" + lineObj.getHTML(null, null, false, tabText, len) + "</span></pre>";
         | 
| 1355 | 
            -
                            return measure.firstChild.firstChild.offsetWidth;
         | 
| 1356 | 
            -
                        }
         | 
| 1357 | 
            -
                        var from = 0, fromX = 0, to = text.length, toX;
         | 
| 1358 | 
            -
                        // Guess a suitable upper bound for our search.
         | 
| 1359 | 
            -
                        var estimated = Math.min(to, Math.ceil(x / charWidth()));
         | 
| 1360 | 
            -
                        for (;;) {
         | 
| 1361 | 
            -
                            var estX = getX(estimated);
         | 
| 1362 | 
            -
                            if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
         | 
| 1363 | 
            -
                            else {toX = estX; to = estimated; break;}
         | 
| 1364 | 
            -
                        }
         | 
| 1365 | 
            -
                        if (x > toX) return to;
         | 
| 1366 | 
            -
                        // Try to guess a suitable lower bound as well.
         | 
| 1367 | 
            -
                        estimated = Math.floor(to * 0.8); estX = getX(estimated);
         | 
| 1368 | 
            -
                        if (estX < x) {from = estimated; fromX = estX;}
         | 
| 1369 | 
            -
                        // Do a binary search between these bounds.
         | 
| 1370 | 
            -
                        for (;;) {
         | 
| 1371 | 
            -
                            if (to - from <= 1) return (toX - x > x - fromX) ? from : to;
         | 
| 1372 | 
            -
                            var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
         | 
| 1373 | 
            -
                            if (middleX > x) {to = middle; toX = middleX;}
         | 
| 1374 | 
            -
                            else {from = middle; fromX = middleX;}
         | 
| 1375 | 
            -
                        }
         | 
| 1376 | 
            -
                    }
         | 
| 1377 | 
            -
             | 
| 1378 | 
            -
                    var tempId = Math.floor(Math.random() * 0xffffff).toString(16);
         | 
| 1379 | 
            -
                    function measureLine(line, ch) {
         | 
| 1380 | 
            -
                        var extra = "";
         | 
| 1381 | 
            -
                        // Include extra text at the end to make sure the measured line is wrapped in the right way.
         | 
| 1382 | 
            -
                        if (options.lineWrapping) {
         | 
| 1383 | 
            -
                            var end = line.text.indexOf(" ", ch + 2);
         | 
| 1384 | 
            -
                            extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));
         | 
| 1385 | 
            -
                        }
         | 
| 1386 | 
            -
                        measure.innerHTML = "<pre>" + line.getHTML(null, null, false, tabText, ch) +
         | 
| 1387 | 
            -
                            '<span id="CodeMirror-temp-' + tempId + '">' + htmlEscape(line.text.charAt(ch) || " ") + "</span>" +
         | 
| 1388 | 
            -
                            extra + "</pre>";
         | 
| 1389 | 
            -
                        var elt = document.getElementById("CodeMirror-temp-" + tempId);
         | 
| 1390 | 
            -
                        var top = elt.offsetTop, left = elt.offsetLeft;
         | 
| 1391 | 
            -
                        // Older IEs report zero offsets for spans directly after a wrap
         | 
| 1392 | 
            -
                        if (ie && ch && top == 0 && left == 0) {
         | 
| 1393 | 
            -
                            var backup = document.createElement("span");
         | 
| 1394 | 
            -
                            backup.innerHTML = "x";
         | 
| 1395 | 
            -
                            elt.parentNode.insertBefore(backup, elt.nextSibling);
         | 
| 1396 | 
            -
                            top = backup.offsetTop;
         | 
| 1397 | 
            -
                        }
         | 
| 1398 | 
            -
                        return {top: top, left: left};
         | 
| 1399 | 
            -
                    }
         | 
| 1400 | 
            -
                    function localCoords(pos, inLineWrap) {
         | 
| 1401 | 
            -
                        var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));
         | 
| 1402 | 
            -
                        if (pos.ch == 0) x = 0;
         | 
| 1403 | 
            -
                        else {
         | 
| 1404 | 
            -
                            var sp = measureLine(getLine(pos.line), pos.ch);
         | 
| 1405 | 
            -
                            x = sp.left;
         | 
| 1406 | 
            -
                            if (options.lineWrapping) y += Math.max(0, sp.top);
         | 
| 1407 | 
            -
                        }
         | 
| 1408 | 
            -
                        return {x: x, y: y, yBot: y + lh};
         | 
| 1409 | 
            -
                    }
         | 
| 1410 | 
            -
                    // Coords must be lineSpace-local
         | 
| 1411 | 
            -
                    function coordsChar(x, y) {
         | 
| 1412 | 
            -
                        if (y < 0) y = 0;
         | 
| 1413 | 
            -
                        var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
         | 
| 1414 | 
            -
                        var lineNo = lineAtHeight(doc, heightPos);
         | 
| 1415 | 
            -
                        if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};
         | 
| 1416 | 
            -
                        var lineObj = getLine(lineNo), text = lineObj.text;
         | 
| 1417 | 
            -
                        var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
         | 
| 1418 | 
            -
                        if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
         | 
| 1419 | 
            -
                        function getX(len) {
         | 
| 1420 | 
            -
                            var sp = measureLine(lineObj, len);
         | 
| 1421 | 
            -
                            if (tw) {
         | 
| 1422 | 
            -
                                var off = Math.round(sp.top / th);
         | 
| 1423 | 
            -
                                return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
         | 
| 1424 | 
            -
                            }
         | 
| 1425 | 
            -
                            return sp.left;
         | 
| 1426 | 
            -
                        }
         | 
| 1427 | 
            -
                        var from = 0, fromX = 0, to = text.length, toX;
         | 
| 1428 | 
            -
                        // Guess a suitable upper bound for our search.
         | 
| 1429 | 
            -
                        var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));
         | 
| 1430 | 
            -
                        for (;;) {
         | 
| 1431 | 
            -
                            var estX = getX(estimated);
         | 
| 1432 | 
            -
                            if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
         | 
| 1433 | 
            -
                            else {toX = estX; to = estimated; break;}
         | 
| 1434 | 
            -
                        }
         | 
| 1435 | 
            -
                        if (x > toX) return {line: lineNo, ch: to};
         | 
| 1436 | 
            -
                        // Try to guess a suitable lower bound as well.
         | 
| 1437 | 
            -
                        estimated = Math.floor(to * 0.8); estX = getX(estimated);
         | 
| 1438 | 
            -
                        if (estX < x) {from = estimated; fromX = estX;}
         | 
| 1439 | 
            -
                        // Do a binary search between these bounds.
         | 
| 1440 | 
            -
                        for (;;) {
         | 
| 1441 | 
            -
                            if (to - from <= 1) return {line: lineNo, ch: (toX - x > x - fromX) ? from : to};
         | 
| 1442 | 
            -
                            var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
         | 
| 1443 | 
            -
                            if (middleX > x) {to = middle; toX = middleX;}
         | 
| 1444 | 
            -
                            else {from = middle; fromX = middleX;}
         | 
| 1445 | 
            -
                        }
         | 
| 1446 | 
            -
                    }
         | 
| 1447 | 
            -
                    function pageCoords(pos) {
         | 
| 1448 | 
            -
                        var local = localCoords(pos, true), off = eltOffset(lineSpace);
         | 
| 1449 | 
            -
                        return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
         | 
| 1450 | 
            -
                    }
         | 
| 1451 | 
            -
             | 
| 1452 | 
            -
                    var cachedHeight, cachedHeightFor, measureText;
         | 
| 1453 | 
            -
                    function textHeight() {
         | 
| 1454 | 
            -
                        if (measureText == null) {
         | 
| 1455 | 
            -
                            measureText = "<pre>";
         | 
| 1456 | 
            -
                            for (var i = 0; i < 49; ++i) measureText += "x<br/>";
         | 
| 1457 | 
            -
                            measureText += "x</pre>";
         | 
| 1458 | 
            -
                        }
         | 
| 1459 | 
            -
                        var offsetHeight = lineDiv.clientHeight;
         | 
| 1460 | 
            -
                        if (offsetHeight == cachedHeightFor) return cachedHeight;
         | 
| 1461 | 
            -
                        cachedHeightFor = offsetHeight;
         | 
| 1462 | 
            -
                        measure.innerHTML = measureText;
         | 
| 1463 | 
            -
                        cachedHeight = measure.firstChild.offsetHeight / 50 || 1;
         | 
| 1464 | 
            -
                        measure.innerHTML = "";
         | 
| 1465 | 
            -
                        return cachedHeight;
         | 
| 1466 | 
            -
                    }
         | 
| 1467 | 
            -
                    var cachedWidth, cachedWidthFor = 0;
         | 
| 1468 | 
            -
                    function charWidth() {
         | 
| 1469 | 
            -
                        if (scroller.clientWidth == cachedWidthFor) return cachedWidth;
         | 
| 1470 | 
            -
                        cachedWidthFor = scroller.clientWidth;
         | 
| 1471 | 
            -
                        return (cachedWidth = stringWidth("x"));
         | 
| 1472 | 
            -
                    }
         | 
| 1473 | 
            -
                    function paddingTop() {return lineSpace.offsetTop;}
         | 
| 1474 | 
            -
                    function paddingLeft() {return lineSpace.offsetLeft;}
         | 
| 1475 | 
            -
             | 
| 1476 | 
            -
                    function posFromMouse(e, liberal) {
         | 
| 1477 | 
            -
                        var offW = eltOffset(scroller, true), x, y;
         | 
| 1478 | 
            -
                        // Fails unpredictably on IE[67] when mouse is dragged around quickly.
         | 
| 1479 | 
            -
                        try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
         | 
| 1480 | 
            -
                        // This is a mess of a heuristic to try and determine whether a
         | 
| 1481 | 
            -
                        // scroll-bar was clicked or not, and to return null if one was
         | 
| 1482 | 
            -
                        // (and !liberal).
         | 
| 1483 | 
            -
                        if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
         | 
| 1484 | 
            -
                            return null;
         | 
| 1485 | 
            -
                        var offL = eltOffset(lineSpace, true);
         | 
| 1486 | 
            -
                        return coordsChar(x - offL.left, y - offL.top);
         | 
| 1487 | 
            -
                    }
         | 
| 1488 | 
            -
                    function onContextMenu(e) {
         | 
| 1489 | 
            -
                        var pos = posFromMouse(e);
         | 
| 1490 | 
            -
                        if (!pos || window.opera) return; // Opera is difficult.
         | 
| 1491 | 
            -
                        if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
         | 
| 1492 | 
            -
                            operation(setCursor)(pos.line, pos.ch);
         | 
| 1493 | 
            -
             | 
| 1494 | 
            -
                        var oldCSS = input.style.cssText;
         | 
| 1495 | 
            -
                        inputDiv.style.position = "absolute";
         | 
| 1496 | 
            -
                        input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
         | 
| 1497 | 
            -
                            "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
         | 
| 1498 | 
            -
                            "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
         | 
| 1499 | 
            -
                        leaveInputAlone = true;
         | 
| 1500 | 
            -
                        var val = input.value = getSelection();
         | 
| 1501 | 
            -
                        focusInput();
         | 
| 1502 | 
            -
                        input.select();
         | 
| 1503 | 
            -
                        function rehide() {
         | 
| 1504 | 
            -
                            var newVal = splitLines(input.value).join("\n");
         | 
| 1505 | 
            -
                            if (newVal != val) operation(replaceSelection)(newVal, "end");
         | 
| 1506 | 
            -
                            inputDiv.style.position = "relative";
         | 
| 1507 | 
            -
                            input.style.cssText = oldCSS;
         | 
| 1508 | 
            -
                            leaveInputAlone = false;
         | 
| 1509 | 
            -
                            resetInput(true);
         | 
| 1510 | 
            -
                            slowPoll();
         | 
| 1511 | 
            -
                        }
         | 
| 1512 | 
            -
             | 
| 1513 | 
            -
                        if (gecko) {
         | 
| 1514 | 
            -
                            e_stop(e);
         | 
| 1515 | 
            -
                            var mouseup = connect(window, "mouseup", function() {
         | 
| 1516 | 
            -
                                mouseup();
         | 
| 1517 | 
            -
                                setTimeout(rehide, 20);
         | 
| 1518 | 
            -
                            }, true);
         | 
| 1519 | 
            -
                        }
         | 
| 1520 | 
            -
                        else {
         | 
| 1521 | 
            -
                            setTimeout(rehide, 50);
         | 
| 1522 | 
            -
                        }
         | 
| 1523 | 
            -
                    }
         | 
| 1524 | 
            -
             | 
| 1525 | 
            -
                    // Cursor-blinking
         | 
| 1526 | 
            -
                    function restartBlink() {
         | 
| 1527 | 
            -
                        clearInterval(blinker);
         | 
| 1528 | 
            -
                        var on = true;
         | 
| 1529 | 
            -
                        cursor.style.visibility = "";
         | 
| 1530 | 
            -
                        blinker = setInterval(function() {
         | 
| 1531 | 
            -
                            cursor.style.visibility = (on = !on) ? "" : "hidden";
         | 
| 1532 | 
            -
                        }, 650);
         | 
| 1533 | 
            -
                    }
         | 
| 1534 | 
            -
             | 
| 1535 | 
            -
                    var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
         | 
| 1536 | 
            -
                    function matchBrackets(autoclear) {
         | 
| 1537 | 
            -
                        var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;
         | 
| 1538 | 
            -
                        var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
         | 
| 1539 | 
            -
                        if (!match) return;
         | 
| 1540 | 
            -
                        var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
         | 
| 1541 | 
            -
                        for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)
         | 
| 1542 | 
            -
                            if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}
         | 
| 1543 | 
            -
             | 
| 1544 | 
            -
                        var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
         | 
| 1545 | 
            -
                        function scan(line, from, to) {
         | 
| 1546 | 
            -
                            if (!line.text) return;
         | 
| 1547 | 
            -
                            var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
         | 
| 1548 | 
            -
                            for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
         | 
| 1549 | 
            -
                                var text = st[i];
         | 
| 1550 | 
            -
                                if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;}
         | 
| 1551 | 
            -
                                for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
         | 
| 1552 | 
            -
                                    if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
         | 
| 1553 | 
            -
                                        var match = matching[cur];
         | 
| 1554 | 
            -
                                        if (match.charAt(1) == ">" == forward) stack.push(cur);
         | 
| 1555 | 
            -
                                        else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
         | 
| 1556 | 
            -
                                        else if (!stack.length) return {pos: pos, match: true};
         | 
| 1557 | 
            -
                                    }
         | 
| 1558 | 
            -
                                }
         | 
| 1559 | 
            -
                            }
         | 
| 1560 | 
            -
                        }
         | 
| 1561 | 
            -
                        for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {
         | 
| 1562 | 
            -
                            var line = getLine(i), first = i == head.line;
         | 
| 1563 | 
            -
                            var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
         | 
| 1564 | 
            -
                            if (found) break;
         | 
| 1565 | 
            -
                        }
         | 
| 1566 | 
            -
                        if (!found) found = {pos: null, match: false};
         | 
| 1567 | 
            -
                        var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
         | 
| 1568 | 
            -
                        var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
         | 
| 1569 | 
            -
                            two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);
         | 
| 1570 | 
            -
                        var clear = operation(function(){one.clear(); two && two.clear();});
         | 
| 1571 | 
            -
                        if (autoclear) setTimeout(clear, 800);
         | 
| 1572 | 
            -
                        else bracketHighlighted = clear;
         | 
| 1573 | 
            -
                    }
         | 
| 1574 | 
            -
             | 
| 1575 | 
            -
                    // Finds the line to start with when starting a parse. Tries to
         | 
| 1576 | 
            -
                    // find a line with a stateAfter, so that it can start with a
         | 
| 1577 | 
            -
                    // valid state. If that fails, it returns the line with the
         | 
| 1578 | 
            -
                    // smallest indentation, which tends to need the least context to
         | 
| 1579 | 
            -
                    // parse correctly.
         | 
| 1580 | 
            -
                    function findStartLine(n) {
         | 
| 1581 | 
            -
                        var minindent, minline;
         | 
| 1582 | 
            -
                        for (var search = n, lim = n - 40; search > lim; --search) {
         | 
| 1583 | 
            -
                            if (search == 0) return 0;
         | 
| 1584 | 
            -
                            var line = getLine(search-1);
         | 
| 1585 | 
            -
                            if (line.stateAfter) return search;
         | 
| 1586 | 
            -
                            var indented = line.indentation(options.tabSize);
         | 
| 1587 | 
            -
                            if (minline == null || minindent > indented) {
         | 
| 1588 | 
            -
                                minline = search - 1;
         | 
| 1589 | 
            -
                                minindent = indented;
         | 
| 1590 | 
            -
                            }
         | 
| 1591 | 
            -
                        }
         | 
| 1592 | 
            -
                        return minline;
         | 
| 1593 | 
            -
                    }
         | 
| 1594 | 
            -
                    function getStateBefore(n) {
         | 
| 1595 | 
            -
                        var start = findStartLine(n), state = start && getLine(start-1).stateAfter;
         | 
| 1596 | 
            -
                        if (!state) state = startState(mode);
         | 
| 1597 | 
            -
                        else state = copyState(mode, state);
         | 
| 1598 | 
            -
                        doc.iter(start, n, function(line) {
         | 
| 1599 | 
            -
                            line.highlight(mode, state, options.tabSize);
         | 
| 1600 | 
            -
                            line.stateAfter = copyState(mode, state);
         | 
| 1601 | 
            -
                        });
         | 
| 1602 | 
            -
                        if (start < n) changes.push({from: start, to: n});
         | 
| 1603 | 
            -
                        if (n < doc.size && !getLine(n).stateAfter) work.push(n);
         | 
| 1604 | 
            -
                        return state;
         | 
| 1605 | 
            -
                    }
         | 
| 1606 | 
            -
                    function highlightLines(start, end) {
         | 
| 1607 | 
            -
                        var state = getStateBefore(start);
         | 
| 1608 | 
            -
                        doc.iter(start, end, function(line) {
         | 
| 1609 | 
            -
                            line.highlight(mode, state, options.tabSize);
         | 
| 1610 | 
            -
                            line.stateAfter = copyState(mode, state);
         | 
| 1611 | 
            -
                        });
         | 
| 1612 | 
            -
                    }
         | 
| 1613 | 
            -
                    function highlightWorker() {
         | 
| 1614 | 
            -
                        var end = +new Date + options.workTime;
         | 
| 1615 | 
            -
                        var foundWork = work.length;
         | 
| 1616 | 
            -
                        while (work.length) {
         | 
| 1617 | 
            -
                            if (!getLine(showingFrom).stateAfter) var task = showingFrom;
         | 
| 1618 | 
            -
                            else var task = work.pop();
         | 
| 1619 | 
            -
                            if (task >= doc.size) continue;
         | 
| 1620 | 
            -
                            var start = findStartLine(task), state = start && getLine(start-1).stateAfter;
         | 
| 1621 | 
            -
                            if (state) state = copyState(mode, state);
         | 
| 1622 | 
            -
                            else state = startState(mode);
         | 
| 1623 | 
            -
             | 
| 1624 | 
            -
                            var unchanged = 0, compare = mode.compareStates, realChange = false,
         | 
| 1625 | 
            -
                                i = start, bail = false;
         | 
| 1626 | 
            -
                            doc.iter(i, doc.size, function(line) {
         | 
| 1627 | 
            -
                                var hadState = line.stateAfter;
         | 
| 1628 | 
            -
                                if (+new Date > end) {
         | 
| 1629 | 
            -
                                    work.push(i);
         | 
| 1630 | 
            -
                                    startWorker(options.workDelay);
         | 
| 1631 | 
            -
                                    if (realChange) changes.push({from: task, to: i + 1});
         | 
| 1632 | 
            -
                                    return (bail = true);
         | 
| 1633 | 
            -
                                }
         | 
| 1634 | 
            -
                                var changed = line.highlight(mode, state, options.tabSize);
         | 
| 1635 | 
            -
                                if (changed) realChange = true;
         | 
| 1636 | 
            -
                                line.stateAfter = copyState(mode, state);
         | 
| 1637 | 
            -
                                if (compare) {
         | 
| 1638 | 
            -
                                    if (hadState && compare(hadState, state)) return true;
         | 
| 1639 | 
            -
                                } else {
         | 
| 1640 | 
            -
                                    if (changed !== false || !hadState) unchanged = 0;
         | 
| 1641 | 
            -
                                    else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, "") == mode.indent(state, "")))
         | 
| 1642 | 
            -
                                        return true;
         | 
| 1643 | 
            -
                                }
         | 
| 1644 | 
            -
                                ++i;
         | 
| 1645 | 
            -
                            });
         | 
| 1646 | 
            -
                            if (bail) return;
         | 
| 1647 | 
            -
                            if (realChange) changes.push({from: task, to: i + 1});
         | 
| 1648 | 
            -
                        }
         | 
| 1649 | 
            -
                        if (foundWork && options.onHighlightComplete)
         | 
| 1650 | 
            -
                            options.onHighlightComplete(instance);
         | 
| 1651 | 
            -
                    }
         | 
| 1652 | 
            -
                    function startWorker(time) {
         | 
| 1653 | 
            -
                        if (!work.length) return;
         | 
| 1654 | 
            -
                        highlight.set(time, operation(highlightWorker));
         | 
| 1655 | 
            -
                    }
         | 
| 1656 | 
            -
             | 
| 1657 | 
            -
                    // Operations are used to wrap changes in such a way that each
         | 
| 1658 | 
            -
                    // change won't have to update the cursor and display (which would
         | 
| 1659 | 
            -
                    // be awkward, slow, and error-prone), but instead updates are
         | 
| 1660 | 
            -
                    // batched and then all combined and executed at once.
         | 
| 1661 | 
            -
                    function startOperation() {
         | 
| 1662 | 
            -
                        updateInput = userSelChange = textChanged = null;
         | 
| 1663 | 
            -
                        changes = []; selectionChanged = false; callbacks = [];
         | 
| 1664 | 
            -
                    }
         | 
| 1665 | 
            -
                    function endOperation() {
         | 
| 1666 | 
            -
                        var reScroll = false, updated;
         | 
| 1667 | 
            -
                        if (selectionChanged) reScroll = !scrollCursorIntoView();
         | 
| 1668 | 
            -
                        if (changes.length) updated = updateDisplay(changes, true);
         | 
| 1669 | 
            -
                        else {
         | 
| 1670 | 
            -
                            if (selectionChanged) updateCursor();
         | 
| 1671 | 
            -
                            if (gutterDirty) updateGutter();
         | 
| 1672 | 
            -
                        }
         | 
| 1673 | 
            -
                        if (reScroll) scrollCursorIntoView();
         | 
| 1674 | 
            -
                        if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
         | 
| 1675 | 
            -
             | 
| 1676 | 
            -
                        if (focused && !leaveInputAlone &&
         | 
| 1677 | 
            -
                            (updateInput === true || (updateInput !== false && selectionChanged)))
         | 
| 1678 | 
            -
                            resetInput(userSelChange);
         | 
| 1679 | 
            -
             | 
| 1680 | 
            -
                        if (selectionChanged && options.matchBrackets)
         | 
| 1681 | 
            -
                            setTimeout(operation(function() {
         | 
| 1682 | 
            -
                                if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
         | 
| 1683 | 
            -
                                if (posEq(sel.from, sel.to)) matchBrackets(false);
         | 
| 1684 | 
            -
                            }), 20);
         | 
| 1685 | 
            -
                        var tc = textChanged, cbs = callbacks; // these can be reset by callbacks
         | 
| 1686 | 
            -
                        if (selectionChanged && options.onCursorActivity)
         | 
| 1687 | 
            -
                            options.onCursorActivity(instance);
         | 
| 1688 | 
            -
                        if (tc && options.onChange && instance)
         | 
| 1689 | 
            -
                            options.onChange(instance, tc);
         | 
| 1690 | 
            -
                        for (var i = 0; i < cbs.length; ++i) cbs[i](instance);
         | 
| 1691 | 
            -
                        if (updated && options.onUpdate) options.onUpdate(instance);
         | 
| 1692 | 
            -
                    }
         | 
| 1693 | 
            -
                    var nestedOperation = 0;
         | 
| 1694 | 
            -
                    function operation(f) {
         | 
| 1695 | 
            -
                        return function() {
         | 
| 1696 | 
            -
                            if (!nestedOperation++) startOperation();
         | 
| 1697 | 
            -
                            try {var result = f.apply(this, arguments);}
         | 
| 1698 | 
            -
                            finally {if (!--nestedOperation) endOperation();}
         | 
| 1699 | 
            -
                            return result;
         | 
| 1700 | 
            -
                        };
         | 
| 1701 | 
            -
                    }
         | 
| 1702 | 
            -
             | 
| 1703 | 
            -
                    for (var ext in extensions)
         | 
| 1704 | 
            -
                        if (extensions.propertyIsEnumerable(ext) &&
         | 
| 1705 | 
            -
                            !instance.propertyIsEnumerable(ext))
         | 
| 1706 | 
            -
                            instance[ext] = extensions[ext];
         | 
| 1707 | 
            -
                    return instance;
         | 
| 1708 | 
            -
                } // (end of function CodeMirror)
         | 
| 1709 | 
            -
             | 
| 1710 | 
            -
                // The default configuration options.
         | 
| 1711 | 
            -
                CodeMirror.defaults = {
         | 
| 1712 | 
            -
                    value: "",
         | 
| 1713 | 
            -
                    mode: null,
         | 
| 1714 | 
            -
                    theme: "default",
         | 
| 1715 | 
            -
                    indentUnit: 2,
         | 
| 1716 | 
            -
                    indentWithTabs: false,
         | 
| 1717 | 
            -
                    tabSize: 4,
         | 
| 1718 | 
            -
                    keyMap: "default",
         | 
| 1719 | 
            -
                    extraKeys: null,
         | 
| 1720 | 
            -
                    electricChars: true,
         | 
| 1721 | 
            -
                    onKeyEvent: null,
         | 
| 1722 | 
            -
                    lineWrapping: false,
         | 
| 1723 | 
            -
                    lineNumbers: false,
         | 
| 1724 | 
            -
                    gutter: false,
         | 
| 1725 | 
            -
                    fixedGutter: false,
         | 
| 1726 | 
            -
                    firstLineNumber: 1,
         | 
| 1727 | 
            -
                    readOnly: false,
         | 
| 1728 | 
            -
                    onChange: null,
         | 
| 1729 | 
            -
                    onCursorActivity: null,
         | 
| 1730 | 
            -
                    onGutterClick: null,
         | 
| 1731 | 
            -
                    onHighlightComplete: null,
         | 
| 1732 | 
            -
                    onUpdate: null,
         | 
| 1733 | 
            -
                    onFocus: null, onBlur: null, onScroll: null,
         | 
| 1734 | 
            -
                    matchBrackets: false,
         | 
| 1735 | 
            -
                    workTime: 100,
         | 
| 1736 | 
            -
                    workDelay: 200,
         | 
| 1737 | 
            -
                    pollInterval: 100,
         | 
| 1738 | 
            -
                    undoDepth: 40,
         | 
| 1739 | 
            -
                    tabindex: null,
         | 
| 1740 | 
            -
                    document: window.document
         | 
| 1741 | 
            -
                };
         | 
| 1742 | 
            -
             | 
| 1743 | 
            -
                var mac = /Mac/.test(navigator.platform);
         | 
| 1744 | 
            -
                var win = /Win/.test(navigator.platform);
         | 
| 1745 | 
            -
             | 
| 1746 | 
            -
                // Known modes, by name and by MIME
         | 
| 1747 | 
            -
                var modes = {}, mimeModes = {};
         | 
| 1748 | 
            -
                CodeMirror.defineMode = function(name, mode) {
         | 
| 1749 | 
            -
                    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
         | 
| 1750 | 
            -
                    modes[name] = mode;
         | 
| 1751 | 
            -
                };
         | 
| 1752 | 
            -
                CodeMirror.defineMIME = function(mime, spec) {
         | 
| 1753 | 
            -
                    mimeModes[mime] = spec;
         | 
| 1754 | 
            -
                };
         | 
| 1755 | 
            -
                CodeMirror.getMode = function(options, spec) {
         | 
| 1756 | 
            -
                    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
         | 
| 1757 | 
            -
                        spec = mimeModes[spec];
         | 
| 1758 | 
            -
                    if (typeof spec == "string")
         | 
| 1759 | 
            -
                        var mname = spec, config = {};
         | 
| 1760 | 
            -
                    else if (spec != null)
         | 
| 1761 | 
            -
                        var mname = spec.name, config = spec;
         | 
| 1762 | 
            -
                    var mfactory = modes[mname];
         | 
| 1763 | 
            -
                    if (!mfactory) {
         | 
| 1764 | 
            -
                        if (window.console) console.warn("No mode " + mname + " found, falling back to plain text.");
         | 
| 1765 | 
            -
                        return CodeMirror.getMode(options, "text/plain");
         | 
| 1766 | 
            -
                    }
         | 
| 1767 | 
            -
                    return mfactory(options, config || {});
         | 
| 1768 | 
            -
                };
         | 
| 1769 | 
            -
                CodeMirror.listModes = function() {
         | 
| 1770 | 
            -
                    var list = [];
         | 
| 1771 | 
            -
                    for (var m in modes)
         | 
| 1772 | 
            -
                        if (modes.propertyIsEnumerable(m)) list.push(m);
         | 
| 1773 | 
            -
                    return list;
         | 
| 1774 | 
            -
                };
         | 
| 1775 | 
            -
                CodeMirror.listMIMEs = function() {
         | 
| 1776 | 
            -
                    var list = [];
         | 
| 1777 | 
            -
                    for (var m in mimeModes)
         | 
| 1778 | 
            -
                        if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
         | 
| 1779 | 
            -
                    return list;
         | 
| 1780 | 
            -
                };
         | 
| 1781 | 
            -
             | 
| 1782 | 
            -
                var extensions = CodeMirror.extensions = {};
         | 
| 1783 | 
            -
                CodeMirror.defineExtension = function(name, func) {
         | 
| 1784 | 
            -
                    extensions[name] = func;
         | 
| 1785 | 
            -
                };
         | 
| 1786 | 
            -
             | 
| 1787 | 
            -
                var commands = CodeMirror.commands = {
         | 
| 1788 | 
            -
                    selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
         | 
| 1789 | 
            -
                    killLine: function(cm) {
         | 
| 1790 | 
            -
                        var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
         | 
| 1791 | 
            -
                        if (!sel && cm.getLine(from.line).length == from.ch) cm.replaceRange("", from, {line: from.line + 1, ch: 0});
         | 
| 1792 | 
            -
                        else cm.replaceRange("", from, sel ? to : {line: from.line});
         | 
| 1793 | 
            -
                    },
         | 
| 1794 | 
            -
                    deleteLine: function(cm) {var l = cm.getCursor().line; cm.replaceRange("", {line: l, ch: 0}, {line: l});},
         | 
| 1795 | 
            -
                    undo: function(cm) {cm.undo();},
         | 
| 1796 | 
            -
                    redo: function(cm) {cm.redo();},
         | 
| 1797 | 
            -
                    goDocStart: function(cm) {cm.setCursor(0, 0, true);},
         | 
| 1798 | 
            -
                    goDocEnd: function(cm) {cm.setSelection({line: cm.lineCount() - 1}, null, true);},
         | 
| 1799 | 
            -
                    goLineStart: function(cm) {cm.setCursor(cm.getCursor().line, 0, true);},
         | 
| 1800 | 
            -
                    goLineStartSmart: function(cm) {
         | 
| 1801 | 
            -
                        var cur = cm.getCursor();
         | 
| 1802 | 
            -
                        var text = cm.getLine(cur.line), firstNonWS = Math.max(0, text.search(/\S/));
         | 
| 1803 | 
            -
                        cm.setCursor(cur.line, cur.ch <= firstNonWS && cur.ch ? 0 : firstNonWS, true);
         | 
| 1804 | 
            -
                    },
         | 
| 1805 | 
            -
                    goLineEnd: function(cm) {cm.setSelection({line: cm.getCursor().line}, null, true);},
         | 
| 1806 | 
            -
                    goLineUp: function(cm) {cm.moveV(-1, "line");},
         | 
| 1807 | 
            -
                    goLineDown: function(cm) {cm.moveV(1, "line");},
         | 
| 1808 | 
            -
                    goPageUp: function(cm) {cm.moveV(-1, "page");},
         | 
| 1809 | 
            -
                    goPageDown: function(cm) {cm.moveV(1, "page");},
         | 
| 1810 | 
            -
                    goCharLeft: function(cm) {cm.moveH(-1, "char");},
         | 
| 1811 | 
            -
                    goCharRight: function(cm) {cm.moveH(1, "char");},
         | 
| 1812 | 
            -
                    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
         | 
| 1813 | 
            -
                    goColumnRight: function(cm) {cm.moveH(1, "column");},
         | 
| 1814 | 
            -
                    goWordLeft: function(cm) {cm.moveH(-1, "word");},
         | 
| 1815 | 
            -
                    goWordRight: function(cm) {cm.moveH(1, "word");},
         | 
| 1816 | 
            -
                    delCharLeft: function(cm) {cm.deleteH(-1, "char");},
         | 
| 1817 | 
            -
                    delCharRight: function(cm) {cm.deleteH(1, "char");},
         | 
| 1818 | 
            -
                    delWordLeft: function(cm) {cm.deleteH(-1, "word");},
         | 
| 1819 | 
            -
                    delWordRight: function(cm) {cm.deleteH(1, "word");},
         | 
| 1820 | 
            -
                    indentAuto: function(cm) {cm.indentSelection("smart");},
         | 
| 1821 | 
            -
                    indentMore: function(cm) {cm.indentSelection("add");},
         | 
| 1822 | 
            -
                    indentLess: function(cm) {cm.indentSelection("subtract");},
         | 
| 1823 | 
            -
                    insertTab: function(cm) {cm.replaceSelection("\t", "end");},
         | 
| 1824 | 
            -
                    transposeChars: function(cm) {
         | 
| 1825 | 
            -
                        var cur = cm.getCursor(), line = cm.getLine(cur.line);
         | 
| 1826 | 
            -
                        if (cur.ch > 0 && cur.ch < line.length - 1)
         | 
| 1827 | 
            -
                            cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
         | 
| 1828 | 
            -
                                {line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});
         | 
| 1829 | 
            -
                    },
         | 
| 1830 | 
            -
                    newlineAndIndent: function(cm) {
         | 
| 1831 | 
            -
                        cm.replaceSelection("\n", "end");
         | 
| 1832 | 
            -
                        cm.indentLine(cm.getCursor().line);
         | 
| 1833 | 
            -
                    },
         | 
| 1834 | 
            -
                    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
         | 
| 1835 | 
            -
                };
         | 
| 1836 | 
            -
             | 
| 1837 | 
            -
                var keyMap = CodeMirror.keyMap = {};
         | 
| 1838 | 
            -
                keyMap.basic = {
         | 
| 1839 | 
            -
                    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
         | 
| 1840 | 
            -
                    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
         | 
| 1841 | 
            -
                    "Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "indentMore", "Shift-Tab": "indentLess",
         | 
| 1842 | 
            -
                    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
         | 
| 1843 | 
            -
                };
         | 
| 1844 | 
            -
                // Note that the save and find-related commands aren't defined by
         | 
| 1845 | 
            -
                // default. Unknown commands are simply ignored.
         | 
| 1846 | 
            -
                keyMap.pcDefault = {
         | 
| 1847 | 
            -
                    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
         | 
| 1848 | 
            -
                    "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
         | 
| 1849 | 
            -
                    "Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
         | 
| 1850 | 
            -
                    "Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
         | 
| 1851 | 
            -
                    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
         | 
| 1852 | 
            -
                    fallthrough: "basic"
         | 
| 1853 | 
            -
                };
         | 
| 1854 | 
            -
                keyMap.macDefault = {
         | 
| 1855 | 
            -
                    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
         | 
| 1856 | 
            -
                    "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goWordLeft",
         | 
| 1857 | 
            -
                    "Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
         | 
| 1858 | 
            -
                    "Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
         | 
| 1859 | 
            -
                    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
         | 
| 1860 | 
            -
                    fallthrough: ["basic", "emacsy"]
         | 
| 1861 | 
            -
                };
         | 
| 1862 | 
            -
                keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
         | 
| 1863 | 
            -
                keyMap.emacsy = {
         | 
| 1864 | 
            -
                    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
         | 
| 1865 | 
            -
                    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
         | 
| 1866 | 
            -
                    "Ctrl-V": "goPageUp", "Shift-Ctrl-V": "goPageDown", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft",
         | 
| 1867 | 
            -
                    "Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
         | 
| 1868 | 
            -
                };
         | 
| 1869 | 
            -
             | 
| 1870 | 
            -
                function lookupKey(name, extraMap, map) {
         | 
| 1871 | 
            -
                    function lookup(name, map, ft) {
         | 
| 1872 | 
            -
                        var found = map[name];
         | 
| 1873 | 
            -
                        if (found != null) return found;
         | 
| 1874 | 
            -
                        if (ft == null) ft = map.fallthrough;
         | 
| 1875 | 
            -
                        if (ft == null) return map.catchall;
         | 
| 1876 | 
            -
                        if (typeof ft == "string") return lookup(name, keyMap[ft]);
         | 
| 1877 | 
            -
                        for (var i = 0, e = ft.length; i < e; ++i) {
         | 
| 1878 | 
            -
                            found = lookup(name, keyMap[ft[i]]);
         | 
| 1879 | 
            -
                            if (found != null) return found;
         | 
| 1880 | 
            -
                        }
         | 
| 1881 | 
            -
                        return null;
         | 
| 1882 | 
            -
                    }
         | 
| 1883 | 
            -
                    return extraMap ? lookup(name, extraMap, map) : lookup(name, keyMap[map]);
         | 
| 1884 | 
            -
                }
         | 
| 1885 | 
            -
                function isModifierKey(event) {
         | 
| 1886 | 
            -
                    var name = keyNames[event.keyCode];
         | 
| 1887 | 
            -
                    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
         | 
| 1888 | 
            -
                }
         | 
| 1889 | 
            -
             | 
| 1890 | 
            -
                CodeMirror.fromTextArea = function(textarea, options) {
         | 
| 1891 | 
            -
                    if (!options) options = {};
         | 
| 1892 | 
            -
                    options.value = textarea.value;
         | 
| 1893 | 
            -
                    if (!options.tabindex && textarea.tabindex)
         | 
| 1894 | 
            -
                        options.tabindex = textarea.tabindex;
         | 
| 1895 | 
            -
             | 
| 1896 | 
            -
                    function save() {textarea.value = instance.getValue();}
         | 
| 1897 | 
            -
                    if (textarea.form) {
         | 
| 1898 | 
            -
                        // Deplorable hack to make the submit method do the right thing.
         | 
| 1899 | 
            -
                        var rmSubmit = connect(textarea.form, "submit", save, true);
         | 
| 1900 | 
            -
                        if (typeof textarea.form.submit == "function") {
         | 
| 1901 | 
            -
                            var realSubmit = textarea.form.submit;
         | 
| 1902 | 
            -
                            function wrappedSubmit() {
         | 
| 1903 | 
            -
                                save();
         | 
| 1904 | 
            -
                                textarea.form.submit = realSubmit;
         | 
| 1905 | 
            -
                                textarea.form.submit();
         | 
| 1906 | 
            -
                                textarea.form.submit = wrappedSubmit;
         | 
| 1907 | 
            -
                            }
         | 
| 1908 | 
            -
                            textarea.form.submit = wrappedSubmit;
         | 
| 1909 | 
            -
                        }
         | 
| 1910 | 
            -
                    }
         | 
| 1911 | 
            -
             | 
| 1912 | 
            -
                    textarea.style.display = "none";
         | 
| 1913 | 
            -
                    var instance = CodeMirror(function(node) {
         | 
| 1914 | 
            -
                        textarea.parentNode.insertBefore(node, textarea.nextSibling);
         | 
| 1915 | 
            -
                    }, options);
         | 
| 1916 | 
            -
                    instance.save = save;
         | 
| 1917 | 
            -
                    instance.getTextArea = function() { return textarea; };
         | 
| 1918 | 
            -
                    instance.toTextArea = function() {
         | 
| 1919 | 
            -
                        save();
         | 
| 1920 | 
            -
                        textarea.parentNode.removeChild(instance.getWrapperElement());
         | 
| 1921 | 
            -
                        textarea.style.display = "";
         | 
| 1922 | 
            -
                        if (textarea.form) {
         | 
| 1923 | 
            -
                            rmSubmit();
         | 
| 1924 | 
            -
                            if (typeof textarea.form.submit == "function")
         | 
| 1925 | 
            -
                                textarea.form.submit = realSubmit;
         | 
| 1926 | 
            -
                        }
         | 
| 1927 | 
            -
                    };
         | 
| 1928 | 
            -
                    return instance;
         | 
| 1929 | 
            -
                };
         | 
| 1930 | 
            -
             | 
| 1931 | 
            -
                // Utility functions for working with state. Exported because modes
         | 
| 1932 | 
            -
                // sometimes need to do this.
         | 
| 1933 | 
            -
                function copyState(mode, state) {
         | 
| 1934 | 
            -
                    if (state === true) return state;
         | 
| 1935 | 
            -
                    if (mode.copyState) return mode.copyState(state);
         | 
| 1936 | 
            -
                    var nstate = {};
         | 
| 1937 | 
            -
                    for (var n in state) {
         | 
| 1938 | 
            -
                        var val = state[n];
         | 
| 1939 | 
            -
                        if (val instanceof Array) val = val.concat([]);
         | 
| 1940 | 
            -
                        nstate[n] = val;
         | 
| 1941 | 
            -
                    }
         | 
| 1942 | 
            -
                    return nstate;
         | 
| 1943 | 
            -
                }
         | 
| 1944 | 
            -
                CodeMirror.copyState = copyState;
         | 
| 1945 | 
            -
                function startState(mode, a1, a2) {
         | 
| 1946 | 
            -
                    return mode.startState ? mode.startState(a1, a2) : true;
         | 
| 1947 | 
            -
                }
         | 
| 1948 | 
            -
                CodeMirror.startState = startState;
         | 
| 1949 | 
            -
             | 
| 1950 | 
            -
                // The character stream used by a mode's parser.
         | 
| 1951 | 
            -
                function StringStream(string, tabSize) {
         | 
| 1952 | 
            -
                    this.pos = this.start = 0;
         | 
| 1953 | 
            -
                    this.string = string;
         | 
| 1954 | 
            -
                    this.tabSize = tabSize || 8;
         | 
| 1955 | 
            -
                }
         | 
| 1956 | 
            -
                StringStream.prototype = {
         | 
| 1957 | 
            -
                    eol: function() {return this.pos >= this.string.length;},
         | 
| 1958 | 
            -
                    sol: function() {return this.pos == 0;},
         | 
| 1959 | 
            -
                    peek: function() {return this.string.charAt(this.pos);},
         | 
| 1960 | 
            -
                    next: function() {
         | 
| 1961 | 
            -
                        if (this.pos < this.string.length)
         | 
| 1962 | 
            -
                            return this.string.charAt(this.pos++);
         | 
| 1963 | 
            -
                    },
         | 
| 1964 | 
            -
                    eat: function(match) {
         | 
| 1965 | 
            -
                        var ch = this.string.charAt(this.pos);
         | 
| 1966 | 
            -
                        if (typeof match == "string") var ok = ch == match;
         | 
| 1967 | 
            -
                        else var ok = ch && (match.test ? match.test(ch) : match(ch));
         | 
| 1968 | 
            -
                        if (ok) {++this.pos; return ch;}
         | 
| 1969 | 
            -
                    },
         | 
| 1970 | 
            -
                    eatWhile: function(match) {
         | 
| 1971 | 
            -
                        var start = this.pos;
         | 
| 1972 | 
            -
                        while (this.eat(match)){}
         | 
| 1973 | 
            -
                        return this.pos > start;
         | 
| 1974 | 
            -
                    },
         | 
| 1975 | 
            -
                    eatSpace: function() {
         | 
| 1976 | 
            -
                        var start = this.pos;
         | 
| 1977 | 
            -
                        while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
         | 
| 1978 | 
            -
                        return this.pos > start;
         | 
| 1979 | 
            -
                    },
         | 
| 1980 | 
            -
                    skipToEnd: function() {this.pos = this.string.length;},
         | 
| 1981 | 
            -
                    skipTo: function(ch) {
         | 
| 1982 | 
            -
                        var found = this.string.indexOf(ch, this.pos);
         | 
| 1983 | 
            -
                        if (found > -1) {this.pos = found; return true;}
         | 
| 1984 | 
            -
                    },
         | 
| 1985 | 
            -
                    backUp: function(n) {this.pos -= n;},
         | 
| 1986 | 
            -
                    column: function() {return countColumn(this.string, this.start, this.tabSize);},
         | 
| 1987 | 
            -
                    indentation: function() {return countColumn(this.string, null, this.tabSize);},
         | 
| 1988 | 
            -
                    match: function(pattern, consume, caseInsensitive) {
         | 
| 1989 | 
            -
                        if (typeof pattern == "string") {
         | 
| 1990 | 
            -
                            function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
         | 
| 1991 | 
            -
                            if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
         | 
| 1992 | 
            -
                                if (consume !== false) this.pos += pattern.length;
         | 
| 1993 | 
            -
                                return true;
         | 
| 1994 | 
            -
                            }
         | 
| 1995 | 
            -
                        }
         | 
| 1996 | 
            -
                        else {
         | 
| 1997 | 
            -
                            var match = this.string.slice(this.pos).match(pattern);
         | 
| 1998 | 
            -
                            if (match && consume !== false) this.pos += match[0].length;
         | 
| 1999 | 
            -
                            return match;
         | 
| 2000 | 
            -
                        }
         | 
| 2001 | 
            -
                    },
         | 
| 2002 | 
            -
                    current: function(){return this.string.slice(this.start, this.pos);}
         | 
| 2003 | 
            -
                };
         | 
| 2004 | 
            -
                CodeMirror.StringStream = StringStream;
         | 
| 2005 | 
            -
             | 
| 2006 | 
            -
                function MarkedText(from, to, className, set) {
         | 
| 2007 | 
            -
                    this.from = from; this.to = to; this.style = className; this.set = set;
         | 
| 2008 | 
            -
                }
         | 
| 2009 | 
            -
                MarkedText.prototype = {
         | 
| 2010 | 
            -
                    attach: function(line) { this.set.push(line); },
         | 
| 2011 | 
            -
                    detach: function(line) {
         | 
| 2012 | 
            -
                        var ix = indexOf(this.set, line);
         | 
| 2013 | 
            -
                        if (ix > -1) this.set.splice(ix, 1);
         | 
| 2014 | 
            -
                    },
         | 
| 2015 | 
            -
                    split: function(pos, lenBefore) {
         | 
| 2016 | 
            -
                        if (this.to <= pos && this.to != null) return null;
         | 
| 2017 | 
            -
                        var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
         | 
| 2018 | 
            -
                        var to = this.to == null ? null : this.to - pos + lenBefore;
         | 
| 2019 | 
            -
                        return new MarkedText(from, to, this.style, this.set);
         | 
| 2020 | 
            -
                    },
         | 
| 2021 | 
            -
                    dup: function() { return new MarkedText(null, null, this.style, this.set); },
         | 
| 2022 | 
            -
                    clipTo: function(fromOpen, from, toOpen, to, diff) {
         | 
| 2023 | 
            -
                        if (this.from != null && this.from >= from)
         | 
| 2024 | 
            -
                            this.from = Math.max(to, this.from) + diff;
         | 
| 2025 | 
            -
                        if (this.to != null && this.to > from)
         | 
| 2026 | 
            -
                            this.to = to < this.to ? this.to + diff : from;
         | 
| 2027 | 
            -
                        if (fromOpen && to > this.from && (to < this.to || this.to == null))
         | 
| 2028 | 
            -
                            this.from = null;
         | 
| 2029 | 
            -
                        if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
         | 
| 2030 | 
            -
                            this.to = null;
         | 
| 2031 | 
            -
                    },
         | 
| 2032 | 
            -
                    isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
         | 
| 2033 | 
            -
                    sameSet: function(x) { return this.set == x.set; }
         | 
| 2034 | 
            -
                };
         | 
| 2035 | 
            -
             | 
| 2036 | 
            -
                function Bookmark(pos) {
         | 
| 2037 | 
            -
                    this.from = pos; this.to = pos; this.line = null;
         | 
| 2038 | 
            -
                }
         | 
| 2039 | 
            -
                Bookmark.prototype = {
         | 
| 2040 | 
            -
                    attach: function(line) { this.line = line; },
         | 
| 2041 | 
            -
                    detach: function(line) { if (this.line == line) this.line = null; },
         | 
| 2042 | 
            -
                    split: function(pos, lenBefore) {
         | 
| 2043 | 
            -
                        if (pos < this.from) {
         | 
| 2044 | 
            -
                            this.from = this.to = (this.from - pos) + lenBefore;
         | 
| 2045 | 
            -
                            return this;
         | 
| 2046 | 
            -
                        }
         | 
| 2047 | 
            -
                    },
         | 
| 2048 | 
            -
                    isDead: function() { return this.from > this.to; },
         | 
| 2049 | 
            -
                    clipTo: function(fromOpen, from, toOpen, to, diff) {
         | 
| 2050 | 
            -
                        if ((fromOpen || from < this.from) && (toOpen || to > this.to)) {
         | 
| 2051 | 
            -
                            this.from = 0; this.to = -1;
         | 
| 2052 | 
            -
                        } else if (this.from > from) {
         | 
| 2053 | 
            -
                            this.from = this.to = Math.max(to, this.from) + diff;
         | 
| 2054 | 
            -
                        }
         | 
| 2055 | 
            -
                    },
         | 
| 2056 | 
            -
                    sameSet: function(x) { return false; },
         | 
| 2057 | 
            -
                    find: function() {
         | 
| 2058 | 
            -
                        if (!this.line || !this.line.parent) return null;
         | 
| 2059 | 
            -
                        return {line: lineNo(this.line), ch: this.from};
         | 
| 2060 | 
            -
                    },
         | 
| 2061 | 
            -
                    clear: function() {
         | 
| 2062 | 
            -
                        if (this.line) {
         | 
| 2063 | 
            -
                            var found = indexOf(this.line.marked, this);
         | 
| 2064 | 
            -
                            if (found != -1) this.line.marked.splice(found, 1);
         | 
| 2065 | 
            -
                            this.line = null;
         | 
| 2066 | 
            -
                        }
         | 
| 2067 | 
            -
                    }
         | 
| 2068 | 
            -
                };
         | 
| 2069 | 
            -
             | 
| 2070 | 
            -
                // Line objects. These hold state related to a line, including
         | 
| 2071 | 
            -
                // highlighting info (the styles array).
         | 
| 2072 | 
            -
                function Line(text, styles) {
         | 
| 2073 | 
            -
                    this.styles = styles || [text, null];
         | 
| 2074 | 
            -
                    this.text = text;
         | 
| 2075 | 
            -
                    this.height = 1;
         | 
| 2076 | 
            -
                    this.marked = this.gutterMarker = this.className = this.handlers = null;
         | 
| 2077 | 
            -
                    this.stateAfter = this.parent = this.hidden = null;
         | 
| 2078 | 
            -
                }
         | 
| 2079 | 
            -
                Line.inheritMarks = function(text, orig) {
         | 
| 2080 | 
            -
                    var ln = new Line(text), mk = orig && orig.marked;
         | 
| 2081 | 
            -
                    if (mk) {
         | 
| 2082 | 
            -
                        for (var i = 0; i < mk.length; ++i) {
         | 
| 2083 | 
            -
                            if (mk[i].to == null && mk[i].style) {
         | 
| 2084 | 
            -
                                var newmk = ln.marked || (ln.marked = []), mark = mk[i];
         | 
| 2085 | 
            -
                                var nmark = mark.dup(); newmk.push(nmark); nmark.attach(ln);
         | 
| 2086 | 
            -
                            }
         | 
| 2087 | 
            -
                        }
         | 
| 2088 | 
            -
                    }
         | 
| 2089 | 
            -
                    return ln;
         | 
| 2090 | 
            -
                }
         | 
| 2091 | 
            -
                Line.prototype = {
         | 
| 2092 | 
            -
                    // Replace a piece of a line, keeping the styles around it intact.
         | 
| 2093 | 
            -
                    replace: function(from, to_, text) {
         | 
| 2094 | 
            -
                        var st = [], mk = this.marked, to = to_ == null ? this.text.length : to_;
         | 
| 2095 | 
            -
                        copyStyles(0, from, this.styles, st);
         | 
| 2096 | 
            -
                        if (text) st.push(text, null);
         | 
| 2097 | 
            -
                        copyStyles(to, this.text.length, this.styles, st);
         | 
| 2098 | 
            -
                        this.styles = st;
         | 
| 2099 | 
            -
                        this.text = this.text.slice(0, from) + text + this.text.slice(to);
         | 
| 2100 | 
            -
                        this.stateAfter = null;
         | 
| 2101 | 
            -
                        if (mk) {
         | 
| 2102 | 
            -
                            var diff = text.length - (to - from);
         | 
| 2103 | 
            -
                            for (var i = 0, mark = mk[i]; i < mk.length; ++i) {
         | 
| 2104 | 
            -
                                mark.clipTo(from == null, from || 0, to_ == null, to, diff);
         | 
| 2105 | 
            -
                                if (mark.isDead()) {mark.detach(this); mk.splice(i--, 1);}
         | 
| 2106 | 
            -
                            }
         | 
| 2107 | 
            -
                        }
         | 
| 2108 | 
            -
                    },
         | 
| 2109 | 
            -
                    // Split a part off a line, keeping styles and markers intact.
         | 
| 2110 | 
            -
                    split: function(pos, textBefore) {
         | 
| 2111 | 
            -
                        var st = [textBefore, null], mk = this.marked;
         | 
| 2112 | 
            -
                        copyStyles(pos, this.text.length, this.styles, st);
         | 
| 2113 | 
            -
                        var taken = new Line(textBefore + this.text.slice(pos), st);
         | 
| 2114 | 
            -
                        if (mk) {
         | 
| 2115 | 
            -
                            for (var i = 0; i < mk.length; ++i) {
         | 
| 2116 | 
            -
                                var mark = mk[i];
         | 
| 2117 | 
            -
                                var newmark = mark.split(pos, textBefore.length);
         | 
| 2118 | 
            -
                                if (newmark) {
         | 
| 2119 | 
            -
                                    if (!taken.marked) taken.marked = [];
         | 
| 2120 | 
            -
                                    taken.marked.push(newmark); newmark.attach(taken);
         | 
| 2121 | 
            -
                                }
         | 
| 2122 | 
            -
                            }
         | 
| 2123 | 
            -
                        }
         | 
| 2124 | 
            -
                        return taken;
         | 
| 2125 | 
            -
                    },
         | 
| 2126 | 
            -
                    append: function(line) {
         | 
| 2127 | 
            -
                        var mylen = this.text.length, mk = line.marked, mymk = this.marked;
         | 
| 2128 | 
            -
                        this.text += line.text;
         | 
| 2129 | 
            -
                        copyStyles(0, line.text.length, line.styles, this.styles);
         | 
| 2130 | 
            -
                        if (mymk) {
         | 
| 2131 | 
            -
                            for (var i = 0; i < mymk.length; ++i)
         | 
| 2132 | 
            -
                                if (mymk[i].to == null) mymk[i].to = mylen;
         | 
| 2133 | 
            -
                        }
         | 
| 2134 | 
            -
                        if (mk && mk.length) {
         | 
| 2135 | 
            -
                            if (!mymk) this.marked = mymk = [];
         | 
| 2136 | 
            -
                            outer: for (var i = 0; i < mk.length; ++i) {
         | 
| 2137 | 
            -
                                var mark = mk[i];
         | 
| 2138 | 
            -
                                if (!mark.from) {
         | 
| 2139 | 
            -
                                    for (var j = 0; j < mymk.length; ++j) {
         | 
| 2140 | 
            -
                                        var mymark = mymk[j];
         | 
| 2141 | 
            -
                                        if (mymark.to == mylen && mymark.sameSet(mark)) {
         | 
| 2142 | 
            -
                                            mymark.to = mark.to == null ? null : mark.to + mylen;
         | 
| 2143 | 
            -
                                            if (mymark.isDead()) {
         | 
| 2144 | 
            -
                                                mymark.detach(this);
         | 
| 2145 | 
            -
                                                mk.splice(i--, 1);
         | 
| 2146 | 
            -
                                            }
         | 
| 2147 | 
            -
                                            continue outer;
         | 
| 2148 | 
            -
                                        }
         | 
| 2149 | 
            -
                                    }
         | 
| 2150 | 
            -
                                }
         | 
| 2151 | 
            -
                                mymk.push(mark);
         | 
| 2152 | 
            -
                                mark.attach(this);
         | 
| 2153 | 
            -
                                mark.from += mylen;
         | 
| 2154 | 
            -
                                if (mark.to != null) mark.to += mylen;
         | 
| 2155 | 
            -
                            }
         | 
| 2156 | 
            -
                        }
         | 
| 2157 | 
            -
                    },
         | 
| 2158 | 
            -
                    fixMarkEnds: function(other) {
         | 
| 2159 | 
            -
                        var mk = this.marked, omk = other.marked;
         | 
| 2160 | 
            -
                        if (!mk) return;
         | 
| 2161 | 
            -
                        for (var i = 0; i < mk.length; ++i) {
         | 
| 2162 | 
            -
                            var mark = mk[i], close = mark.to == null;
         | 
| 2163 | 
            -
                            if (close && omk) {
         | 
| 2164 | 
            -
                                for (var j = 0; j < omk.length; ++j)
         | 
| 2165 | 
            -
                                    if (omk[j].sameSet(mark)) {close = false; break;}
         | 
| 2166 | 
            -
                            }
         | 
| 2167 | 
            -
                            if (close) mark.to = this.text.length;
         | 
| 2168 | 
            -
                        }
         | 
| 2169 | 
            -
                    },
         | 
| 2170 | 
            -
                    fixMarkStarts: function() {
         | 
| 2171 | 
            -
                        var mk = this.marked;
         | 
| 2172 | 
            -
                        if (!mk) return;
         | 
| 2173 | 
            -
                        for (var i = 0; i < mk.length; ++i)
         | 
| 2174 | 
            -
                            if (mk[i].from == null) mk[i].from = 0;
         | 
| 2175 | 
            -
                    },
         | 
| 2176 | 
            -
                    addMark: function(mark) {
         | 
| 2177 | 
            -
                        mark.attach(this);
         | 
| 2178 | 
            -
                        if (this.marked == null) this.marked = [];
         | 
| 2179 | 
            -
                        this.marked.push(mark);
         | 
| 2180 | 
            -
                        this.marked.sort(function(a, b){return (a.from || 0) - (b.from || 0);});
         | 
| 2181 | 
            -
                    },
         | 
| 2182 | 
            -
                    // Run the given mode's parser over a line, update the styles
         | 
| 2183 | 
            -
                    // array, which contains alternating fragments of text and CSS
         | 
| 2184 | 
            -
                    // classes.
         | 
| 2185 | 
            -
                    highlight: function(mode, state, tabSize) {
         | 
| 2186 | 
            -
                        var stream = new StringStream(this.text, tabSize), st = this.styles, pos = 0;
         | 
| 2187 | 
            -
                        var changed = false, curWord = st[0], prevWord;
         | 
| 2188 | 
            -
                        if (this.text == "" && mode.blankLine) mode.blankLine(state);
         | 
| 2189 | 
            -
                        while (!stream.eol()) {
         | 
| 2190 | 
            -
                            var style = mode.token(stream, state);
         | 
| 2191 | 
            -
                            var substr = this.text.slice(stream.start, stream.pos);
         | 
| 2192 | 
            -
                            stream.start = stream.pos;
         | 
| 2193 | 
            -
                            if (pos && st[pos-1] == style)
         | 
| 2194 | 
            -
                                st[pos-2] += substr;
         | 
| 2195 | 
            -
                            else if (substr) {
         | 
| 2196 | 
            -
                                if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true;
         | 
| 2197 | 
            -
                                st[pos++] = substr; st[pos++] = style;
         | 
| 2198 | 
            -
                                prevWord = curWord; curWord = st[pos];
         | 
| 2199 | 
            -
                            }
         | 
| 2200 | 
            -
                            // Give up when line is ridiculously long
         | 
| 2201 | 
            -
                            if (stream.pos > 5000) {
         | 
| 2202 | 
            -
                                st[pos++] = this.text.slice(stream.pos); st[pos++] = null;
         | 
| 2203 | 
            -
                                break;
         | 
| 2204 | 
            -
                            }
         | 
| 2205 | 
            -
                        }
         | 
| 2206 | 
            -
                        if (st.length != pos) {st.length = pos; changed = true;}
         | 
| 2207 | 
            -
                        if (pos && st[pos-2] != prevWord) changed = true;
         | 
| 2208 | 
            -
                        // Short lines with simple highlights return null, and are
         | 
| 2209 | 
            -
                        // counted as changed by the driver because they are likely to
         | 
| 2210 | 
            -
                        // highlight the same way in various contexts.
         | 
| 2211 | 
            -
                        return changed || (st.length < 5 && this.text.length < 10 ? null : false);
         | 
| 2212 | 
            -
                    },
         | 
| 2213 | 
            -
                    // Fetch the parser token for a given character. Useful for hacks
         | 
| 2214 | 
            -
                    // that want to inspect the mode state (say, for completion).
         | 
| 2215 | 
            -
                    getTokenAt: function(mode, state, ch) {
         | 
| 2216 | 
            -
                        var txt = this.text, stream = new StringStream(txt);
         | 
| 2217 | 
            -
                        while (stream.pos < ch && !stream.eol()) {
         | 
| 2218 | 
            -
                            stream.start = stream.pos;
         | 
| 2219 | 
            -
                            var style = mode.token(stream, state);
         | 
| 2220 | 
            -
                        }
         | 
| 2221 | 
            -
                        return {start: stream.start,
         | 
| 2222 | 
            -
                            end: stream.pos,
         | 
| 2223 | 
            -
                            string: stream.current(),
         | 
| 2224 | 
            -
                            className: style || null,
         | 
| 2225 | 
            -
                            state: state};
         | 
| 2226 | 
            -
                    },
         | 
| 2227 | 
            -
                    indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
         | 
| 2228 | 
            -
                    // Produces an HTML fragment for the line, taking selection,
         | 
| 2229 | 
            -
                    // marking, and highlighting into account.
         | 
| 2230 | 
            -
                    getHTML: function(sfrom, sto, includePre, tabText, endAt) {
         | 
| 2231 | 
            -
                        var html = [], first = true;
         | 
| 2232 | 
            -
                        if (includePre)
         | 
| 2233 | 
            -
                            html.push(this.className ? '<pre class="' + this.className + '">': "<pre>");
         | 
| 2234 | 
            -
                        function span(text, style) {
         | 
| 2235 | 
            -
                            if (!text) return;
         | 
| 2236 | 
            -
                            // Work around a bug where, in some compat modes, IE ignores leading spaces
         | 
| 2237 | 
            -
                            if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
         | 
| 2238 | 
            -
                            first = false;
         | 
| 2239 | 
            -
                            if (style) html.push('<span class="', style, '">', htmlEscape(text).replace(/\t/g, tabText), "</span>");
         | 
| 2240 | 
            -
                            else html.push(htmlEscape(text).replace(/\t/g, tabText));
         | 
| 2241 | 
            -
                        }
         | 
| 2242 | 
            -
                        var st = this.styles, allText = this.text, marked = this.marked;
         | 
| 2243 | 
            -
                        if (sfrom == sto) sfrom = null;
         | 
| 2244 | 
            -
                        var len = allText.length;
         | 
| 2245 | 
            -
                        if (endAt != null) len = Math.min(endAt, len);
         | 
| 2246 | 
            -
             | 
| 2247 | 
            -
                        if (!allText && endAt == null)
         | 
| 2248 | 
            -
                            span(" ", sfrom != null && sto == null ? "CodeMirror-selected" : null);
         | 
| 2249 | 
            -
                        else if (!marked && sfrom == null)
         | 
| 2250 | 
            -
                            for (var i = 0, ch = 0; ch < len; i+=2) {
         | 
| 2251 | 
            -
                                var str = st[i], style = st[i+1], l = str.length;
         | 
| 2252 | 
            -
                                if (ch + l > len) str = str.slice(0, len - ch);
         | 
| 2253 | 
            -
                                ch += l;
         | 
| 2254 | 
            -
                                span(str, style && "cm-" + style);
         | 
| 2255 | 
            -
                            }
         | 
| 2256 | 
            -
                        else {
         | 
| 2257 | 
            -
                            var pos = 0, i = 0, text = "", style, sg = 0;
         | 
| 2258 | 
            -
                            var markpos = -1, mark = null;
         | 
| 2259 | 
            -
                            function nextMark() {
         | 
| 2260 | 
            -
                                if (marked) {
         | 
| 2261 | 
            -
                                    markpos += 1;
         | 
| 2262 | 
            -
                                    mark = (markpos < marked.length) ? marked[markpos] : null;
         | 
| 2263 | 
            -
                                }
         | 
| 2264 | 
            -
                            }
         | 
| 2265 | 
            -
                            nextMark();
         | 
| 2266 | 
            -
                            while (pos < len) {
         | 
| 2267 | 
            -
                                var upto = len;
         | 
| 2268 | 
            -
                                var extraStyle = "";
         | 
| 2269 | 
            -
                                if (sfrom != null) {
         | 
| 2270 | 
            -
                                    if (sfrom > pos) upto = sfrom;
         | 
| 2271 | 
            -
                                    else if (sto == null || sto > pos) {
         | 
| 2272 | 
            -
                                        extraStyle = " CodeMirror-selected";
         | 
| 2273 | 
            -
                                        if (sto != null) upto = Math.min(upto, sto);
         | 
| 2274 | 
            -
                                    }
         | 
| 2275 | 
            -
                                }
         | 
| 2276 | 
            -
                                while (mark && mark.to != null && mark.to <= pos) nextMark();
         | 
| 2277 | 
            -
                                if (mark) {
         | 
| 2278 | 
            -
                                    if (mark.from > pos) upto = Math.min(upto, mark.from);
         | 
| 2279 | 
            -
                                    else {
         | 
| 2280 | 
            -
                                        extraStyle += " " + mark.style;
         | 
| 2281 | 
            -
                                        if (mark.to != null) upto = Math.min(upto, mark.to);
         | 
| 2282 | 
            -
                                    }
         | 
| 2283 | 
            -
                                }
         | 
| 2284 | 
            -
                                for (;;) {
         | 
| 2285 | 
            -
                                    var end = pos + text.length;
         | 
| 2286 | 
            -
                                    var appliedStyle = style;
         | 
| 2287 | 
            -
                                    if (extraStyle) appliedStyle = style ? style + extraStyle : extraStyle;
         | 
| 2288 | 
            -
                                    span(end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
         | 
| 2289 | 
            -
                                    if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
         | 
| 2290 | 
            -
                                    pos = end;
         | 
| 2291 | 
            -
                                    text = st[i++]; style = "cm-" + st[i++];
         | 
| 2292 | 
            -
                                }
         | 
| 2293 | 
            -
                            }
         | 
| 2294 | 
            -
                            if (sfrom != null && sto == null) span(" ", "CodeMirror-selected");
         | 
| 2295 | 
            -
                        }
         | 
| 2296 | 
            -
                        if (includePre) html.push("</pre>");
         | 
| 2297 | 
            -
                        return html.join("");
         | 
| 2298 | 
            -
                    },
         | 
| 2299 | 
            -
                    cleanUp: function() {
         | 
| 2300 | 
            -
                        this.parent = null;
         | 
| 2301 | 
            -
                        if (this.marked)
         | 
| 2302 | 
            -
                            for (var i = 0, e = this.marked.length; i < e; ++i) this.marked[i].detach(this);
         | 
| 2303 | 
            -
                    }
         | 
| 2304 | 
            -
                };
         | 
| 2305 | 
            -
                // Utility used by replace and split above
         | 
| 2306 | 
            -
                function copyStyles(from, to, source, dest) {
         | 
| 2307 | 
            -
                    for (var i = 0, pos = 0, state = 0; pos < to; i+=2) {
         | 
| 2308 | 
            -
                        var part = source[i], end = pos + part.length;
         | 
| 2309 | 
            -
                        if (state == 0) {
         | 
| 2310 | 
            -
                            if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);
         | 
| 2311 | 
            -
                            if (end >= from) state = 1;
         | 
| 2312 | 
            -
                        }
         | 
| 2313 | 
            -
                        else if (state == 1) {
         | 
| 2314 | 
            -
                            if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);
         | 
| 2315 | 
            -
                            else dest.push(part, source[i+1]);
         | 
| 2316 | 
            -
                        }
         | 
| 2317 | 
            -
                        pos = end;
         | 
| 2318 | 
            -
                    }
         | 
| 2319 | 
            -
                }
         | 
| 2320 | 
            -
             | 
| 2321 | 
            -
                // Data structure that holds the sequence of lines.
         | 
| 2322 | 
            -
                function LeafChunk(lines) {
         | 
| 2323 | 
            -
                    this.lines = lines;
         | 
| 2324 | 
            -
                    this.parent = null;
         | 
| 2325 | 
            -
                    for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
         | 
| 2326 | 
            -
                        lines[i].parent = this;
         | 
| 2327 | 
            -
                        height += lines[i].height;
         | 
| 2328 | 
            -
                    }
         | 
| 2329 | 
            -
                    this.height = height;
         | 
| 2330 | 
            -
                }
         | 
| 2331 | 
            -
                LeafChunk.prototype = {
         | 
| 2332 | 
            -
                    chunkSize: function() { return this.lines.length; },
         | 
| 2333 | 
            -
                    remove: function(at, n, callbacks) {
         | 
| 2334 | 
            -
                        for (var i = at, e = at + n; i < e; ++i) {
         | 
| 2335 | 
            -
                            var line = this.lines[i];
         | 
| 2336 | 
            -
                            this.height -= line.height;
         | 
| 2337 | 
            -
                            line.cleanUp();
         | 
| 2338 | 
            -
                            if (line.handlers)
         | 
| 2339 | 
            -
                                for (var j = 0; j < line.handlers.length; ++j) callbacks.push(line.handlers[j]);
         | 
| 2340 | 
            -
                        }
         | 
| 2341 | 
            -
                        this.lines.splice(at, n);
         | 
| 2342 | 
            -
                    },
         | 
| 2343 | 
            -
                    collapse: function(lines) {
         | 
| 2344 | 
            -
                        lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
         | 
| 2345 | 
            -
                    },
         | 
| 2346 | 
            -
                    insertHeight: function(at, lines, height) {
         | 
| 2347 | 
            -
                        this.height += height;
         | 
| 2348 | 
            -
                        this.lines.splice.apply(this.lines, [at, 0].concat(lines));
         | 
| 2349 | 
            -
                        for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
         | 
| 2350 | 
            -
                    },
         | 
| 2351 | 
            -
                    iterN: function(at, n, op) {
         | 
| 2352 | 
            -
                        for (var e = at + n; at < e; ++at)
         | 
| 2353 | 
            -
                            if (op(this.lines[at])) return true;
         | 
| 2354 | 
            -
                    }
         | 
| 2355 | 
            -
                };
         | 
| 2356 | 
            -
                function BranchChunk(children) {
         | 
| 2357 | 
            -
                    this.children = children;
         | 
| 2358 | 
            -
                    var size = 0, height = 0;
         | 
| 2359 | 
            -
                    for (var i = 0, e = children.length; i < e; ++i) {
         | 
| 2360 | 
            -
                        var ch = children[i];
         | 
| 2361 | 
            -
                        size += ch.chunkSize(); height += ch.height;
         | 
| 2362 | 
            -
                        ch.parent = this;
         | 
| 2363 | 
            -
                    }
         | 
| 2364 | 
            -
                    this.size = size;
         | 
| 2365 | 
            -
                    this.height = height;
         | 
| 2366 | 
            -
                    this.parent = null;
         | 
| 2367 | 
            -
                }
         | 
| 2368 | 
            -
                BranchChunk.prototype = {
         | 
| 2369 | 
            -
                    chunkSize: function() { return this.size; },
         | 
| 2370 | 
            -
                    remove: function(at, n, callbacks) {
         | 
| 2371 | 
            -
                        this.size -= n;
         | 
| 2372 | 
            -
                        for (var i = 0; i < this.children.length; ++i) {
         | 
| 2373 | 
            -
                            var child = this.children[i], sz = child.chunkSize();
         | 
| 2374 | 
            -
                            if (at < sz) {
         | 
| 2375 | 
            -
                                var rm = Math.min(n, sz - at), oldHeight = child.height;
         | 
| 2376 | 
            -
                                child.remove(at, rm, callbacks);
         | 
| 2377 | 
            -
                                this.height -= oldHeight - child.height;
         | 
| 2378 | 
            -
                                if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
         | 
| 2379 | 
            -
                                if ((n -= rm) == 0) break;
         | 
| 2380 | 
            -
                                at = 0;
         | 
| 2381 | 
            -
                            } else at -= sz;
         | 
| 2382 | 
            -
                        }
         | 
| 2383 | 
            -
                        if (this.size - n < 25) {
         | 
| 2384 | 
            -
                            var lines = [];
         | 
| 2385 | 
            -
                            this.collapse(lines);
         | 
| 2386 | 
            -
                            this.children = [new LeafChunk(lines)];
         | 
| 2387 | 
            -
                        }
         | 
| 2388 | 
            -
                    },
         | 
| 2389 | 
            -
                    collapse: function(lines) {
         | 
| 2390 | 
            -
                        for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
         | 
| 2391 | 
            -
                    },
         | 
| 2392 | 
            -
                    insert: function(at, lines) {
         | 
| 2393 | 
            -
                        var height = 0;
         | 
| 2394 | 
            -
                        for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
         | 
| 2395 | 
            -
                        this.insertHeight(at, lines, height);
         | 
| 2396 | 
            -
                    },
         | 
| 2397 | 
            -
                    insertHeight: function(at, lines, height) {
         | 
| 2398 | 
            -
                        this.size += lines.length;
         | 
| 2399 | 
            -
                        this.height += height;
         | 
| 2400 | 
            -
                        for (var i = 0, e = this.children.length; i < e; ++i) {
         | 
| 2401 | 
            -
                            var child = this.children[i], sz = child.chunkSize();
         | 
| 2402 | 
            -
                            if (at <= sz) {
         | 
| 2403 | 
            -
                                child.insertHeight(at, lines, height);
         | 
| 2404 | 
            -
                                if (child.lines && child.lines.length > 50) {
         | 
| 2405 | 
            -
                                    while (child.lines.length > 50) {
         | 
| 2406 | 
            -
                                        var spilled = child.lines.splice(child.lines.length - 25, 25);
         | 
| 2407 | 
            -
                                        var newleaf = new LeafChunk(spilled);
         | 
| 2408 | 
            -
                                        child.height -= newleaf.height;
         | 
| 2409 | 
            -
                                        this.children.splice(i + 1, 0, newleaf);
         | 
| 2410 | 
            -
                                        newleaf.parent = this;
         | 
| 2411 | 
            -
                                    }
         | 
| 2412 | 
            -
                                    this.maybeSpill();
         | 
| 2413 | 
            -
                                }
         | 
| 2414 | 
            -
                                break;
         | 
| 2415 | 
            -
                            }
         | 
| 2416 | 
            -
                            at -= sz;
         | 
| 2417 | 
            -
                        }
         | 
| 2418 | 
            -
                    },
         | 
| 2419 | 
            -
                    maybeSpill: function() {
         | 
| 2420 | 
            -
                        if (this.children.length <= 10) return;
         | 
| 2421 | 
            -
                        var me = this;
         | 
| 2422 | 
            -
                        do {
         | 
| 2423 | 
            -
                            var spilled = me.children.splice(me.children.length - 5, 5);
         | 
| 2424 | 
            -
                            var sibling = new BranchChunk(spilled);
         | 
| 2425 | 
            -
                            if (!me.parent) { // Become the parent node
         | 
| 2426 | 
            -
                                var copy = new BranchChunk(me.children);
         | 
| 2427 | 
            -
                                copy.parent = me;
         | 
| 2428 | 
            -
                                me.children = [copy, sibling];
         | 
| 2429 | 
            -
                                me = copy;
         | 
| 2430 | 
            -
                            } else {
         | 
| 2431 | 
            -
                                me.size -= sibling.size;
         | 
| 2432 | 
            -
                                me.height -= sibling.height;
         | 
| 2433 | 
            -
                                var myIndex = indexOf(me.parent.children, me);
         | 
| 2434 | 
            -
                                me.parent.children.splice(myIndex + 1, 0, sibling);
         | 
| 2435 | 
            -
                            }
         | 
| 2436 | 
            -
                            sibling.parent = me.parent;
         | 
| 2437 | 
            -
                        } while (me.children.length > 10);
         | 
| 2438 | 
            -
                        me.parent.maybeSpill();
         | 
| 2439 | 
            -
                    },
         | 
| 2440 | 
            -
                    iter: function(from, to, op) { this.iterN(from, to - from, op); },
         | 
| 2441 | 
            -
                    iterN: function(at, n, op) {
         | 
| 2442 | 
            -
                        for (var i = 0, e = this.children.length; i < e; ++i) {
         | 
| 2443 | 
            -
                            var child = this.children[i], sz = child.chunkSize();
         | 
| 2444 | 
            -
                            if (at < sz) {
         | 
| 2445 | 
            -
                                var used = Math.min(n, sz - at);
         | 
| 2446 | 
            -
                                if (child.iterN(at, used, op)) return true;
         | 
| 2447 | 
            -
                                if ((n -= used) == 0) break;
         | 
| 2448 | 
            -
                                at = 0;
         | 
| 2449 | 
            -
                            } else at -= sz;
         | 
| 2450 | 
            -
                        }
         | 
| 2451 | 
            -
                    }
         | 
| 2452 | 
            -
                };
         | 
| 2453 | 
            -
             | 
| 2454 | 
            -
                function getLineAt(chunk, n) {
         | 
| 2455 | 
            -
                    while (!chunk.lines) {
         | 
| 2456 | 
            -
                        for (var i = 0;; ++i) {
         | 
| 2457 | 
            -
                            var child = chunk.children[i], sz = child.chunkSize();
         | 
| 2458 | 
            -
                            if (n < sz) { chunk = child; break; }
         | 
| 2459 | 
            -
                            n -= sz;
         | 
| 2460 | 
            -
                        }
         | 
| 2461 | 
            -
                    }
         | 
| 2462 | 
            -
                    return chunk.lines[n];
         | 
| 2463 | 
            -
                }
         | 
| 2464 | 
            -
                function lineNo(line) {
         | 
| 2465 | 
            -
                    if (line.parent == null) return null;
         | 
| 2466 | 
            -
                    var cur = line.parent, no = indexOf(cur.lines, line);
         | 
| 2467 | 
            -
                    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
         | 
| 2468 | 
            -
                        for (var i = 0, e = chunk.children.length; ; ++i) {
         | 
| 2469 | 
            -
                            if (chunk.children[i] == cur) break;
         | 
| 2470 | 
            -
                            no += chunk.children[i].chunkSize();
         | 
| 2471 | 
            -
                        }
         | 
| 2472 | 
            -
                    }
         | 
| 2473 | 
            -
                    return no;
         | 
| 2474 | 
            -
                }
         | 
| 2475 | 
            -
                function lineAtHeight(chunk, h) {
         | 
| 2476 | 
            -
                    var n = 0;
         | 
| 2477 | 
            -
                    outer: do {
         | 
| 2478 | 
            -
                        for (var i = 0, e = chunk.children.length; i < e; ++i) {
         | 
| 2479 | 
            -
                            var child = chunk.children[i], ch = child.height;
         | 
| 2480 | 
            -
                            if (h < ch) { chunk = child; continue outer; }
         | 
| 2481 | 
            -
                            h -= ch;
         | 
| 2482 | 
            -
                            n += child.chunkSize();
         | 
| 2483 | 
            -
                        }
         | 
| 2484 | 
            -
                        return n;
         | 
| 2485 | 
            -
                    } while (!chunk.lines);
         | 
| 2486 | 
            -
                    for (var i = 0, e = chunk.lines.length; i < e; ++i) {
         | 
| 2487 | 
            -
                        var line = chunk.lines[i], lh = line.height;
         | 
| 2488 | 
            -
                        if (h < lh) break;
         | 
| 2489 | 
            -
                        h -= lh;
         | 
| 2490 | 
            -
                    }
         | 
| 2491 | 
            -
                    return n + i;
         | 
| 2492 | 
            -
                }
         | 
| 2493 | 
            -
                function heightAtLine(chunk, n) {
         | 
| 2494 | 
            -
                    var h = 0;
         | 
| 2495 | 
            -
                    outer: do {
         | 
| 2496 | 
            -
                        for (var i = 0, e = chunk.children.length; i < e; ++i) {
         | 
| 2497 | 
            -
                            var child = chunk.children[i], sz = child.chunkSize();
         | 
| 2498 | 
            -
                            if (n < sz) { chunk = child; continue outer; }
         | 
| 2499 | 
            -
                            n -= sz;
         | 
| 2500 | 
            -
                            h += child.height;
         | 
| 2501 | 
            -
                        }
         | 
| 2502 | 
            -
                        return h;
         | 
| 2503 | 
            -
                    } while (!chunk.lines);
         | 
| 2504 | 
            -
                    for (var i = 0; i < n; ++i) h += chunk.lines[i].height;
         | 
| 2505 | 
            -
                    return h;
         | 
| 2506 | 
            -
                }
         | 
| 2507 | 
            -
             | 
| 2508 | 
            -
                // The history object 'chunks' changes that are made close together
         | 
| 2509 | 
            -
                // and at almost the same time into bigger undoable units.
         | 
| 2510 | 
            -
                function History() {
         | 
| 2511 | 
            -
                    this.time = 0;
         | 
| 2512 | 
            -
                    this.done = []; this.undone = [];
         | 
| 2513 | 
            -
                }
         | 
| 2514 | 
            -
                History.prototype = {
         | 
| 2515 | 
            -
                    addChange: function(start, added, old) {
         | 
| 2516 | 
            -
                        this.undone.length = 0;
         | 
| 2517 | 
            -
                        var time = +new Date, last = this.done[this.done.length - 1];
         | 
| 2518 | 
            -
                        if (time - this.time > 400 || !last ||
         | 
| 2519 | 
            -
                            last.start > start + added || last.start + last.added < start - last.added + last.old.length)
         | 
| 2520 | 
            -
                            this.done.push({start: start, added: added, old: old});
         | 
| 2521 | 
            -
                        else {
         | 
| 2522 | 
            -
                            var oldoff = 0;
         | 
| 2523 | 
            -
                            if (start < last.start) {
         | 
| 2524 | 
            -
                                for (var i = last.start - start - 1; i >= 0; --i)
         | 
| 2525 | 
            -
                                    last.old.unshift(old[i]);
         | 
| 2526 | 
            -
                                last.added += last.start - start;
         | 
| 2527 | 
            -
                                last.start = start;
         | 
| 2528 | 
            -
                            }
         | 
| 2529 | 
            -
                            else if (last.start < start) {
         | 
| 2530 | 
            -
                                oldoff = start - last.start;
         | 
| 2531 | 
            -
                                added += oldoff;
         | 
| 2532 | 
            -
                            }
         | 
| 2533 | 
            -
                            for (var i = last.added - oldoff, e = old.length; i < e; ++i)
         | 
| 2534 | 
            -
                                last.old.push(old[i]);
         | 
| 2535 | 
            -
                            if (last.added < added) last.added = added;
         | 
| 2536 | 
            -
                        }
         | 
| 2537 | 
            -
                        this.time = time;
         | 
| 2538 | 
            -
                    }
         | 
| 2539 | 
            -
                };
         | 
| 2540 | 
            -
             | 
| 2541 | 
            -
                function stopMethod() {e_stop(this);}
         | 
| 2542 | 
            -
                // Ensure an event has a stop method.
         | 
| 2543 | 
            -
                function addStop(event) {
         | 
| 2544 | 
            -
                    if (!event.stop) event.stop = stopMethod;
         | 
| 2545 | 
            -
                    return event;
         | 
| 2546 | 
            -
                }
         | 
| 2547 | 
            -
             | 
| 2548 | 
            -
                function e_preventDefault(e) {
         | 
| 2549 | 
            -
                    if (e.preventDefault) e.preventDefault();
         | 
| 2550 | 
            -
                    else e.returnValue = false;
         | 
| 2551 | 
            -
                }
         | 
| 2552 | 
            -
                function e_stopPropagation(e) {
         | 
| 2553 | 
            -
                    if (e.stopPropagation) e.stopPropagation();
         | 
| 2554 | 
            -
                    else e.cancelBubble = true;
         | 
| 2555 | 
            -
                }
         | 
| 2556 | 
            -
                function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
         | 
| 2557 | 
            -
                CodeMirror.e_stop = e_stop;
         | 
| 2558 | 
            -
                CodeMirror.e_preventDefault = e_preventDefault;
         | 
| 2559 | 
            -
                CodeMirror.e_stopPropagation = e_stopPropagation;
         | 
| 2560 | 
            -
             | 
| 2561 | 
            -
                function e_target(e) {return e.target || e.srcElement;}
         | 
| 2562 | 
            -
                function e_button(e) {
         | 
| 2563 | 
            -
                    if (e.which) return e.which;
         | 
| 2564 | 
            -
                    else if (e.button & 1) return 1;
         | 
| 2565 | 
            -
                    else if (e.button & 2) return 3;
         | 
| 2566 | 
            -
                    else if (e.button & 4) return 2;
         | 
| 2567 | 
            -
                }
         | 
| 2568 | 
            -
             | 
| 2569 | 
            -
                // Event handler registration. If disconnect is true, it'll return a
         | 
| 2570 | 
            -
                // function that unregisters the handler.
         | 
| 2571 | 
            -
                function connect(node, type, handler, disconnect) {
         | 
| 2572 | 
            -
                    if (typeof node.addEventListener == "function") {
         | 
| 2573 | 
            -
                        node.addEventListener(type, handler, false);
         | 
| 2574 | 
            -
                        if (disconnect) return function() {node.removeEventListener(type, handler, false);};
         | 
| 2575 | 
            -
                    }
         | 
| 2576 | 
            -
                    else {
         | 
| 2577 | 
            -
                        var wrapHandler = function(event) {handler(event || window.event);};
         | 
| 2578 | 
            -
                        node.attachEvent("on" + type, wrapHandler);
         | 
| 2579 | 
            -
                        if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
         | 
| 2580 | 
            -
                    }
         | 
| 2581 | 
            -
                }
         | 
| 2582 | 
            -
                CodeMirror.connect = connect;
         | 
| 2583 | 
            -
             | 
| 2584 | 
            -
                function Delayed() {this.id = null;}
         | 
| 2585 | 
            -
                Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
         | 
| 2586 | 
            -
             | 
| 2587 | 
            -
                // Detect drag-and-drop
         | 
| 2588 | 
            -
                var dragAndDrop = function() {
         | 
| 2589 | 
            -
                    // IE8 has ondragstart and ondrop properties, but doesn't seem to
         | 
| 2590 | 
            -
                    // actually support ondragstart the way it's supposed to work.
         | 
| 2591 | 
            -
                    if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
         | 
| 2592 | 
            -
                    var div = document.createElement('div');
         | 
| 2593 | 
            -
                    return "draggable" in div;
         | 
| 2594 | 
            -
                }();
         | 
| 2595 | 
            -
             | 
| 2596 | 
            -
                var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
         | 
| 2597 | 
            -
                var ie = /MSIE \d/.test(navigator.userAgent);
         | 
| 2598 | 
            -
                var webkit = /WebKit\//.test(navigator.userAgent);
         | 
| 2599 | 
            -
             | 
| 2600 | 
            -
                var lineSep = "\n";
         | 
| 2601 | 
            -
                // Feature-detect whether newlines in textareas are converted to \r\n
         | 
| 2602 | 
            -
                (function () {
         | 
| 2603 | 
            -
                    var te = document.createElement("textarea");
         | 
| 2604 | 
            -
                    te.value = "foo\nbar";
         | 
| 2605 | 
            -
                    if (te.value.indexOf("\r") > -1) lineSep = "\r\n";
         | 
| 2606 | 
            -
                }());
         | 
| 2607 | 
            -
             | 
| 2608 | 
            -
                // Counts the column offset in a string, taking tabs into account.
         | 
| 2609 | 
            -
                // Used mostly to find indentation.
         | 
| 2610 | 
            -
                function countColumn(string, end, tabSize) {
         | 
| 2611 | 
            -
                    if (end == null) {
         | 
| 2612 | 
            -
                        end = string.search(/[^\s\u00a0]/);
         | 
| 2613 | 
            -
                        if (end == -1) end = string.length;
         | 
| 2614 | 
            -
                    }
         | 
| 2615 | 
            -
                    for (var i = 0, n = 0; i < end; ++i) {
         | 
| 2616 | 
            -
                        if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
         | 
| 2617 | 
            -
                        else ++n;
         | 
| 2618 | 
            -
                    }
         | 
| 2619 | 
            -
                    return n;
         | 
| 2620 | 
            -
                }
         | 
| 2621 | 
            -
             | 
| 2622 | 
            -
                function computedStyle(elt) {
         | 
| 2623 | 
            -
                    if (elt.currentStyle) return elt.currentStyle;
         | 
| 2624 | 
            -
                    return window.getComputedStyle(elt, null);
         | 
| 2625 | 
            -
                }
         | 
| 2626 | 
            -
             | 
| 2627 | 
            -
                // Find the position of an element by following the offsetParent chain.
         | 
| 2628 | 
            -
                // If screen==true, it returns screen (rather than page) coordinates.
         | 
| 2629 | 
            -
                function eltOffset(node, screen) {
         | 
| 2630 | 
            -
                    var bod = node.ownerDocument.body;
         | 
| 2631 | 
            -
                    var x = 0, y = 0, skipBody = false;
         | 
| 2632 | 
            -
                    for (var n = node; n; n = n.offsetParent) {
         | 
| 2633 | 
            -
                        var ol = n.offsetLeft, ot = n.offsetTop;
         | 
| 2634 | 
            -
                        // Firefox reports weird inverted offsets when the body has a border.
         | 
| 2635 | 
            -
                        if (n == bod) { x += Math.abs(ol); y += Math.abs(ot); }
         | 
| 2636 | 
            -
                        else { x += ol, y += ot; }
         | 
| 2637 | 
            -
                        if (screen && computedStyle(n).position == "fixed")
         | 
| 2638 | 
            -
                            skipBody = true;
         | 
| 2639 | 
            -
                    }
         | 
| 2640 | 
            -
                    var e = screen && !skipBody ? null : bod;
         | 
| 2641 | 
            -
                    for (var n = node.parentNode; n != e; n = n.parentNode)
         | 
| 2642 | 
            -
                        if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;}
         | 
| 2643 | 
            -
                    return {left: x, top: y};
         | 
| 2644 | 
            -
                }
         | 
| 2645 | 
            -
                // Use the faster and saner getBoundingClientRect method when possible.
         | 
| 2646 | 
            -
                if (document.documentElement.getBoundingClientRect != null) eltOffset = function(node, screen) {
         | 
| 2647 | 
            -
                    // Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
         | 
| 2648 | 
            -
                    // since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
         | 
| 2649 | 
            -
                    try { var box = node.getBoundingClientRect(); box = { top: box.top, left: box.left }; }
         | 
| 2650 | 
            -
                    catch(e) { box = {top: 0, left: 0}; }
         | 
| 2651 | 
            -
                    if (!screen) {
         | 
| 2652 | 
            -
                        // Get the toplevel scroll, working around browser differences.
         | 
| 2653 | 
            -
                        if (window.pageYOffset == null) {
         | 
| 2654 | 
            -
                            var t = document.documentElement || document.body.parentNode;
         | 
| 2655 | 
            -
                            if (t.scrollTop == null) t = document.body;
         | 
| 2656 | 
            -
                            box.top += t.scrollTop; box.left += t.scrollLeft;
         | 
| 2657 | 
            -
                        } else {
         | 
| 2658 | 
            -
                            box.top += window.pageYOffset; box.left += window.pageXOffset;
         | 
| 2659 | 
            -
                        }
         | 
| 2660 | 
            -
                    }
         | 
| 2661 | 
            -
                    return box;
         | 
| 2662 | 
            -
                };
         | 
| 2663 | 
            -
             | 
| 2664 | 
            -
                // Get a node's text content.
         | 
| 2665 | 
            -
                function eltText(node) {
         | 
| 2666 | 
            -
                    return node.textContent || node.innerText || node.nodeValue || "";
         | 
| 2667 | 
            -
                }
         | 
| 2668 | 
            -
             | 
| 2669 | 
            -
                // Operations on {line, ch} objects.
         | 
| 2670 | 
            -
                function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
         | 
| 2671 | 
            -
                function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
         | 
| 2672 | 
            -
                function copyPos(x) {return {line: x.line, ch: x.ch};}
         | 
| 2673 | 
            -
             | 
| 2674 | 
            -
                var escapeElement = document.createElement("pre");
         | 
| 2675 | 
            -
                function htmlEscape(str) {
         | 
| 2676 | 
            -
                    escapeElement.textContent = str;
         | 
| 2677 | 
            -
                    return escapeElement.innerHTML;
         | 
| 2678 | 
            -
                }
         | 
| 2679 | 
            -
                // Recent (late 2011) Opera betas insert bogus newlines at the start
         | 
| 2680 | 
            -
                // of the textContent, so we strip those.
         | 
| 2681 | 
            -
                if (htmlEscape("a") == "\na")
         | 
| 2682 | 
            -
                    htmlEscape = function(str) {
         | 
| 2683 | 
            -
                        escapeElement.textContent = str;
         | 
| 2684 | 
            -
                        return escapeElement.innerHTML.slice(1);
         | 
| 2685 | 
            -
                    };
         | 
| 2686 | 
            -
                // Some IEs don't preserve tabs through innerHTML
         | 
| 2687 | 
            -
                else if (htmlEscape("\t") != "\t")
         | 
| 2688 | 
            -
                    htmlEscape = function(str) {
         | 
| 2689 | 
            -
                        escapeElement.innerHTML = "";
         | 
| 2690 | 
            -
                        escapeElement.appendChild(document.createTextNode(str));
         | 
| 2691 | 
            -
                        return escapeElement.innerHTML;
         | 
| 2692 | 
            -
                    };
         | 
| 2693 | 
            -
                CodeMirror.htmlEscape = htmlEscape;
         | 
| 2694 | 
            -
             | 
| 2695 | 
            -
                // Used to position the cursor after an undo/redo by finding the
         | 
| 2696 | 
            -
                // last edited character.
         | 
| 2697 | 
            -
                function editEnd(from, to) {
         | 
| 2698 | 
            -
                    if (!to) return from ? from.length : 0;
         | 
| 2699 | 
            -
                    if (!from) return to.length;
         | 
| 2700 | 
            -
                    for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)
         | 
| 2701 | 
            -
                        if (from.charAt(i) != to.charAt(j)) break;
         | 
| 2702 | 
            -
                    return j + 1;
         | 
| 2703 | 
            -
                }
         | 
| 2704 | 
            -
             | 
| 2705 | 
            -
                function indexOf(collection, elt) {
         | 
| 2706 | 
            -
                    if (collection.indexOf) return collection.indexOf(elt);
         | 
| 2707 | 
            -
                    for (var i = 0, e = collection.length; i < e; ++i)
         | 
| 2708 | 
            -
                        if (collection[i] == elt) return i;
         | 
| 2709 | 
            -
                    return -1;
         | 
| 2710 | 
            -
                }
         | 
| 2711 | 
            -
                function isWordChar(ch) {
         | 
| 2712 | 
            -
                    return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase();
         | 
| 2713 | 
            -
                }
         | 
| 2714 | 
            -
             | 
| 2715 | 
            -
                // See if "".split is the broken IE version, if so, provide an
         | 
| 2716 | 
            -
                // alternative way to split lines.
         | 
| 2717 | 
            -
                var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
         | 
| 2718 | 
            -
                    var pos = 0, nl, result = [];
         | 
| 2719 | 
            -
                    while ((nl = string.indexOf("\n", pos)) > -1) {
         | 
| 2720 | 
            -
                        result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl));
         | 
| 2721 | 
            -
                        pos = nl + 1;
         | 
| 2722 | 
            -
                    }
         | 
| 2723 | 
            -
                    result.push(string.slice(pos));
         | 
| 2724 | 
            -
                    return result;
         | 
| 2725 | 
            -
                } : function(string){return string.split(/\r?\n/);};
         | 
| 2726 | 
            -
                CodeMirror.splitLines = splitLines;
         | 
| 2727 | 
            -
             | 
| 2728 | 
            -
                var hasSelection = window.getSelection ? function(te) {
         | 
| 2729 | 
            -
                    try { return te.selectionStart != te.selectionEnd; }
         | 
| 2730 | 
            -
                    catch(e) { return false; }
         | 
| 2731 | 
            -
                } : function(te) {
         | 
| 2732 | 
            -
                    try {var range = te.ownerDocument.selection.createRange();}
         | 
| 2733 | 
            -
                    catch(e) {}
         | 
| 2734 | 
            -
                    if (!range || range.parentElement() != te) return false;
         | 
| 2735 | 
            -
                    return range.compareEndPoints("StartToEnd", range) != 0;
         | 
| 2736 | 
            -
                };
         | 
| 2737 | 
            -
             | 
| 2738 | 
            -
                CodeMirror.defineMode("null", function() {
         | 
| 2739 | 
            -
                    return {token: function(stream) {stream.skipToEnd();}};
         | 
| 2740 | 
            -
                });
         | 
| 2741 | 
            -
                CodeMirror.defineMIME("text/plain", "null");
         | 
| 2742 | 
            -
             | 
| 2743 | 
            -
                var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
         | 
| 2744 | 
            -
                    19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
         | 
| 2745 | 
            -
                    36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
         | 
| 2746 | 
            -
                    46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 186: ";", 187: "=", 188: ",",
         | 
| 2747 | 
            -
                    189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63276: "PageUp",
         | 
| 2748 | 
            -
                    63277: "PageDown", 63275: "End", 63273: "Home", 63234: "Left", 63232: "Up", 63235: "Right",
         | 
| 2749 | 
            -
                    63233: "Down", 63302: "Insert", 63272: "Delete"};
         | 
| 2750 | 
            -
                CodeMirror.keyNames = keyNames;
         | 
| 2751 | 
            -
                (function() {
         | 
| 2752 | 
            -
                    // Number keys
         | 
| 2753 | 
            -
                    for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
         | 
| 2754 | 
            -
                    // Alphabetic keys
         | 
| 2755 | 
            -
                    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
         | 
| 2756 | 
            -
                    // Function keys
         | 
| 2757 | 
            -
                    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
         | 
| 2758 | 
            -
                })();
         | 
| 2759 | 
            -
             | 
| 2760 | 
            -
                return CodeMirror;
         | 
| 2761 | 
            -
            })();
         | 
| 2762 | 
            -
            CodeMirror.defineMode("xml", function(config, parserConfig) {
         | 
| 2763 | 
            -
                var indentUnit = config.indentUnit;
         | 
| 2764 | 
            -
                var Kludges = parserConfig.htmlMode ? {
         | 
| 2765 | 
            -
                    autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
         | 
| 2766 | 
            -
                        "meta": true, "col": true, "frame": true, "base": true, "area": true},
         | 
| 2767 | 
            -
                    doNotIndent: {"pre": true},
         | 
| 2768 | 
            -
                    allowUnquoted: true
         | 
| 2769 | 
            -
                } : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false};
         | 
| 2770 | 
            -
                var alignCDATA = parserConfig.alignCDATA;
         | 
| 2771 | 
            -
             | 
| 2772 | 
            -
                // Return variables for tokenizers
         | 
| 2773 | 
            -
                var tagName, type;
         | 
| 2774 | 
            -
             | 
| 2775 | 
            -
                function inText(stream, state) {
         | 
| 2776 | 
            -
                    function chain(parser) {
         | 
| 2777 | 
            -
                        state.tokenize = parser;
         | 
| 2778 | 
            -
                        return parser(stream, state);
         | 
| 2779 | 
            -
                    }
         | 
| 2780 | 
            -
             | 
| 2781 | 
            -
                    var ch = stream.next();
         | 
| 2782 | 
            -
                    if (ch == "<") {
         | 
| 2783 | 
            -
                        if (stream.eat("!")) {
         | 
| 2784 | 
            -
                            if (stream.eat("[")) {
         | 
| 2785 | 
            -
                                if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
         | 
| 2786 | 
            -
                                else return null;
         | 
| 2787 | 
            -
                            }
         | 
| 2788 | 
            -
                            else if (stream.match("--")) return chain(inBlock("comment", "-->"));
         | 
| 2789 | 
            -
                            else if (stream.match("DOCTYPE", true, true)) {
         | 
| 2790 | 
            -
                                stream.eatWhile(/[\w\._\-]/);
         | 
| 2791 | 
            -
                                return chain(doctype(1));
         | 
| 2792 | 
            -
                            }
         | 
| 2793 | 
            -
                            else return null;
         | 
| 2794 | 
            -
                        }
         | 
| 2795 | 
            -
                        else if (stream.eat("?")) {
         | 
| 2796 | 
            -
                            stream.eatWhile(/[\w\._\-]/);
         | 
| 2797 | 
            -
                            state.tokenize = inBlock("meta", "?>");
         | 
| 2798 | 
            -
                            return "meta";
         | 
| 2799 | 
            -
                        }
         | 
| 2800 | 
            -
                        else {
         | 
| 2801 | 
            -
                            type = stream.eat("/") ? "closeTag" : "openTag";
         | 
| 2802 | 
            -
                            stream.eatSpace();
         | 
| 2803 | 
            -
                            tagName = "";
         | 
| 2804 | 
            -
                            var c;
         | 
| 2805 | 
            -
                            while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
         | 
| 2806 | 
            -
                            state.tokenize = inTag;
         | 
| 2807 | 
            -
                            return "tag";
         | 
| 2808 | 
            -
                        }
         | 
| 2809 | 
            -
                    }
         | 
| 2810 | 
            -
                    else if (ch == "&") {
         | 
| 2811 | 
            -
                        stream.eatWhile(/[^;]/);
         | 
| 2812 | 
            -
                        stream.eat(";");
         | 
| 2813 | 
            -
                        return "atom";
         | 
| 2814 | 
            -
                    }
         | 
| 2815 | 
            -
                    else {
         | 
| 2816 | 
            -
                        stream.eatWhile(/[^&<]/);
         | 
| 2817 | 
            -
                        return null;
         | 
| 2818 | 
            -
                    }
         | 
| 2819 | 
            -
                }
         | 
| 2820 | 
            -
             | 
| 2821 | 
            -
                function inTag(stream, state) {
         | 
| 2822 | 
            -
                    var ch = stream.next();
         | 
| 2823 | 
            -
                    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
         | 
| 2824 | 
            -
                        state.tokenize = inText;
         | 
| 2825 | 
            -
                        type = ch == ">" ? "endTag" : "selfcloseTag";
         | 
| 2826 | 
            -
                        return "tag";
         | 
| 2827 | 
            -
                    }
         | 
| 2828 | 
            -
                    else if (ch == "=") {
         | 
| 2829 | 
            -
                        type = "equals";
         | 
| 2830 | 
            -
                        return null;
         | 
| 2831 | 
            -
                    }
         | 
| 2832 | 
            -
                    else if (/[\'\"]/.test(ch)) {
         | 
| 2833 | 
            -
                        state.tokenize = inAttribute(ch);
         | 
| 2834 | 
            -
                        return state.tokenize(stream, state);
         | 
| 2835 | 
            -
                    }
         | 
| 2836 | 
            -
                    else {
         | 
| 2837 | 
            -
                        stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
         | 
| 2838 | 
            -
                        return "word";
         | 
| 2839 | 
            -
                    }
         | 
| 2840 | 
            -
                }
         | 
| 2841 | 
            -
             | 
| 2842 | 
            -
                function inAttribute(quote) {
         | 
| 2843 | 
            -
                    return function(stream, state) {
         | 
| 2844 | 
            -
                        while (!stream.eol()) {
         | 
| 2845 | 
            -
                            if (stream.next() == quote) {
         | 
| 2846 | 
            -
                                state.tokenize = inTag;
         | 
| 2847 | 
            -
                                break;
         | 
| 2848 | 
            -
                            }
         | 
| 2849 | 
            -
                        }
         | 
| 2850 | 
            -
                        return "string";
         | 
| 2851 | 
            -
                    };
         | 
| 2852 | 
            -
                }
         | 
| 2853 | 
            -
             | 
| 2854 | 
            -
                function inBlock(style, terminator) {
         | 
| 2855 | 
            -
                    return function(stream, state) {
         | 
| 2856 | 
            -
                        while (!stream.eol()) {
         | 
| 2857 | 
            -
                            if (stream.match(terminator)) {
         | 
| 2858 | 
            -
                                state.tokenize = inText;
         | 
| 2859 | 
            -
                                break;
         | 
| 2860 | 
            -
                            }
         | 
| 2861 | 
            -
                            stream.next();
         | 
| 2862 | 
            -
                        }
         | 
| 2863 | 
            -
                        return style;
         | 
| 2864 | 
            -
                    };
         | 
| 2865 | 
            -
                }
         | 
| 2866 | 
            -
                function doctype(depth) {
         | 
| 2867 | 
            -
                    return function(stream, state) {
         | 
| 2868 | 
            -
                        var ch;
         | 
| 2869 | 
            -
                        while ((ch = stream.next()) != null) {
         | 
| 2870 | 
            -
                            if (ch == "<") {
         | 
| 2871 | 
            -
                                state.tokenize = doctype(depth + 1);
         | 
| 2872 | 
            -
                                return state.tokenize(stream, state);
         | 
| 2873 | 
            -
                            } else if (ch == ">") {
         | 
| 2874 | 
            -
                                if (depth == 1) {
         | 
| 2875 | 
            -
                                    state.tokenize = inText;
         | 
| 2876 | 
            -
                                    break;
         | 
| 2877 | 
            -
                                } else {
         | 
| 2878 | 
            -
                                    state.tokenize = doctype(depth - 1);
         | 
| 2879 | 
            -
                                    return state.tokenize(stream, state);
         | 
| 2880 | 
            -
                                }
         | 
| 2881 | 
            -
                            }
         | 
| 2882 | 
            -
                        }
         | 
| 2883 | 
            -
                        return "meta";
         | 
| 2884 | 
            -
                    };
         | 
| 2885 | 
            -
                }
         | 
| 2886 | 
            -
             | 
| 2887 | 
            -
                var curState, setStyle;
         | 
| 2888 | 
            -
                function pass() {
         | 
| 2889 | 
            -
                    for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
         | 
| 2890 | 
            -
                }
         | 
| 2891 | 
            -
                function cont() {
         | 
| 2892 | 
            -
                    pass.apply(null, arguments);
         | 
| 2893 | 
            -
                    return true;
         | 
| 2894 | 
            -
                }
         | 
| 2895 | 
            -
             | 
| 2896 | 
            -
                function pushContext(tagName, startOfLine) {
         | 
| 2897 | 
            -
                    var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
         | 
| 2898 | 
            -
                    curState.context = {
         | 
| 2899 | 
            -
                        prev: curState.context,
         | 
| 2900 | 
            -
                        tagName: tagName,
         | 
| 2901 | 
            -
                        indent: curState.indented,
         | 
| 2902 | 
            -
                        startOfLine: startOfLine,
         | 
| 2903 | 
            -
                        noIndent: noIndent
         | 
| 2904 | 
            -
                    };
         | 
| 2905 | 
            -
                }
         | 
| 2906 | 
            -
                function popContext() {
         | 
| 2907 | 
            -
                    if (curState.context) curState.context = curState.context.prev;
         | 
| 2908 | 
            -
                }
         | 
| 2909 | 
            -
             | 
| 2910 | 
            -
                function element(type) {
         | 
| 2911 | 
            -
                    if (type == "openTag") {
         | 
| 2912 | 
            -
                        curState.tagName = tagName;
         | 
| 2913 | 
            -
                        return cont(attributes, endtag(curState.startOfLine));
         | 
| 2914 | 
            -
                    } else if (type == "closeTag") {
         | 
| 2915 | 
            -
                        var err = false;
         | 
| 2916 | 
            -
                        if (curState.context) {
         | 
| 2917 | 
            -
                            err = curState.context.tagName != tagName;
         | 
| 2918 | 
            -
                        } else {
         | 
| 2919 | 
            -
                            err = true;
         | 
| 2920 | 
            -
                        }
         | 
| 2921 | 
            -
                        if (err) setStyle = "error";
         | 
| 2922 | 
            -
                        return cont(endclosetag(err));
         | 
| 2923 | 
            -
                    }
         | 
| 2924 | 
            -
                    return cont();
         | 
| 2925 | 
            -
                }
         | 
| 2926 | 
            -
                function endtag(startOfLine) {
         | 
| 2927 | 
            -
                    return function(type) {
         | 
| 2928 | 
            -
                        if (type == "selfcloseTag" ||
         | 
| 2929 | 
            -
                            (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))
         | 
| 2930 | 
            -
                            return cont();
         | 
| 2931 | 
            -
                        if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();}
         | 
| 2932 | 
            -
                        return cont();
         | 
| 2933 | 
            -
                    };
         | 
| 2934 | 
            -
                }
         | 
| 2935 | 
            -
                function endclosetag(err) {
         | 
| 2936 | 
            -
                    return function(type) {
         | 
| 2937 | 
            -
                        if (err) setStyle = "error";
         | 
| 2938 | 
            -
                        if (type == "endTag") { popContext(); return cont(); }
         | 
| 2939 | 
            -
                        setStyle = "error";
         | 
| 2940 | 
            -
                        return cont(arguments.callee);
         | 
| 2941 | 
            -
                    }
         | 
| 2942 | 
            -
                }
         | 
| 2943 | 
            -
             | 
| 2944 | 
            -
                function attributes(type) {
         | 
| 2945 | 
            -
                    if (type == "word") {setStyle = "attribute"; return cont(attributes);}
         | 
| 2946 | 
            -
                    if (type == "equals") return cont(attvalue, attributes);
         | 
| 2947 | 
            -
                    if (type == "string") {setStyle = "error"; return cont(attributes);}
         | 
| 2948 | 
            -
                    return pass();
         | 
| 2949 | 
            -
                }
         | 
| 2950 | 
            -
                function attvalue(type) {
         | 
| 2951 | 
            -
                    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
         | 
| 2952 | 
            -
                    if (type == "string") return cont(attvaluemaybe);
         | 
| 2953 | 
            -
                    return pass();
         | 
| 2954 | 
            -
                }
         | 
| 2955 | 
            -
                function attvaluemaybe(type) {
         | 
| 2956 | 
            -
                    if (type == "string") return cont(attvaluemaybe);
         | 
| 2957 | 
            -
                    else return pass();
         | 
| 2958 | 
            -
                }
         | 
| 2959 | 
            -
             | 
| 2960 | 
            -
                return {
         | 
| 2961 | 
            -
                    startState: function() {
         | 
| 2962 | 
            -
                        return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
         | 
| 2963 | 
            -
                    },
         | 
| 2964 | 
            -
             | 
| 2965 | 
            -
                    token: function(stream, state) {
         | 
| 2966 | 
            -
                        if (stream.sol()) {
         | 
| 2967 | 
            -
                            state.startOfLine = true;
         | 
| 2968 | 
            -
                            state.indented = stream.indentation();
         | 
| 2969 | 
            -
                        }
         | 
| 2970 | 
            -
                        if (stream.eatSpace()) return null;
         | 
| 2971 | 
            -
             | 
| 2972 | 
            -
                        setStyle = type = tagName = null;
         | 
| 2973 | 
            -
                        var style = state.tokenize(stream, state);
         | 
| 2974 | 
            -
                        state.type = type;
         | 
| 2975 | 
            -
                        if ((style || type) && style != "comment") {
         | 
| 2976 | 
            -
                            curState = state;
         | 
| 2977 | 
            -
                            while (true) {
         | 
| 2978 | 
            -
                                var comb = state.cc.pop() || element;
         | 
| 2979 | 
            -
                                if (comb(type || style)) break;
         | 
| 2980 | 
            -
                            }
         | 
| 2981 | 
            -
                        }
         | 
| 2982 | 
            -
                        state.startOfLine = false;
         | 
| 2983 | 
            -
                        return setStyle || style;
         | 
| 2984 | 
            -
                    },
         | 
| 2985 | 
            -
             | 
| 2986 | 
            -
                    indent: function(state, textAfter, fullLine) {
         | 
| 2987 | 
            -
                        var context = state.context;
         | 
| 2988 | 
            -
                        if ((state.tokenize != inTag && state.tokenize != inText) ||
         | 
| 2989 | 
            -
                            context && context.noIndent)
         | 
| 2990 | 
            -
                            return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
         | 
| 2991 | 
            -
                        if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
         | 
| 2992 | 
            -
                        if (context && /^<\//.test(textAfter))
         | 
| 2993 | 
            -
                            context = context.prev;
         | 
| 2994 | 
            -
                        while (context && !context.startOfLine)
         | 
| 2995 | 
            -
                            context = context.prev;
         | 
| 2996 | 
            -
                        if (context) return context.indent + indentUnit;
         | 
| 2997 | 
            -
                        else return 0;
         | 
| 2998 | 
            -
                    },
         | 
| 2999 | 
            -
             | 
| 3000 | 
            -
                    compareStates: function(a, b) {
         | 
| 3001 | 
            -
                        if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
         | 
| 3002 | 
            -
                        for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
         | 
| 3003 | 
            -
                            if (!ca || !cb) return ca == cb;
         | 
| 3004 | 
            -
                            if (ca.tagName != cb.tagName) return false;
         | 
| 3005 | 
            -
                        }
         | 
| 3006 | 
            -
                    },
         | 
| 3007 | 
            -
             | 
| 3008 | 
            -
                    electricChars: "/"
         | 
| 3009 | 
            -
                };
         | 
| 3010 | 
            -
            });
         | 
| 3011 | 
            -
             | 
| 3012 | 
            -
            CodeMirror.defineMIME("application/xml", "xml");
         | 
| 3013 | 
            -
            CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
         | 
| 3014 | 
            -
            CodeMirror.defineMode("javascript", function(config, parserConfig) {
         | 
| 3015 | 
            -
                var indentUnit = config.indentUnit;
         | 
| 3016 | 
            -
                var jsonMode = parserConfig.json;
         | 
| 3017 | 
            -
             | 
| 3018 | 
            -
                // Tokenizer
         | 
| 3019 | 
            -
             | 
| 3020 | 
            -
                var keywords = function(){
         | 
| 3021 | 
            -
                    function kw(type) {return {type: type, style: "keyword"};}
         | 
| 3022 | 
            -
                    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
         | 
| 3023 | 
            -
                    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
         | 
| 3024 | 
            -
                    return {
         | 
| 3025 | 
            -
                        "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
         | 
| 3026 | 
            -
                        "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
         | 
| 3027 | 
            -
                        "var": kw("var"), "const": kw("var"), "let": kw("var"),
         | 
| 3028 | 
            -
                        "function": kw("function"), "catch": kw("catch"),
         | 
| 3029 | 
            -
                        "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
         | 
| 3030 | 
            -
                        "in": operator, "typeof": operator, "instanceof": operator,
         | 
| 3031 | 
            -
                        "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
         | 
| 3032 | 
            -
                    };
         | 
| 3033 | 
            -
                }();
         | 
| 3034 | 
            -
             | 
| 3035 | 
            -
                var isOperatorChar = /[+\-*&%=<>!?|]/;
         | 
| 3036 | 
            -
             | 
| 3037 | 
            -
                function chain(stream, state, f) {
         | 
| 3038 | 
            -
                    state.tokenize = f;
         | 
| 3039 | 
            -
                    return f(stream, state);
         | 
| 3040 | 
            -
                }
         | 
| 3041 | 
            -
             | 
| 3042 | 
            -
                function nextUntilUnescaped(stream, end) {
         | 
| 3043 | 
            -
                    var escaped = false, next;
         | 
| 3044 | 
            -
                    while ((next = stream.next()) != null) {
         | 
| 3045 | 
            -
                        if (next == end && !escaped)
         | 
| 3046 | 
            -
                            return false;
         | 
| 3047 | 
            -
                        escaped = !escaped && next == "\\";
         | 
| 3048 | 
            -
                    }
         | 
| 3049 | 
            -
                    return escaped;
         | 
| 3050 | 
            -
                }
         | 
| 3051 | 
            -
             | 
| 3052 | 
            -
                // Used as scratch variables to communicate multiple values without
         | 
| 3053 | 
            -
                // consing up tons of objects.
         | 
| 3054 | 
            -
                var type, content;
         | 
| 3055 | 
            -
                function ret(tp, style, cont) {
         | 
| 3056 | 
            -
                    type = tp; content = cont;
         | 
| 3057 | 
            -
                    return style;
         | 
| 3058 | 
            -
                }
         | 
| 3059 | 
            -
             | 
| 3060 | 
            -
                function jsTokenBase(stream, state) {
         | 
| 3061 | 
            -
                    var ch = stream.next();
         | 
| 3062 | 
            -
                    if (ch == '"' || ch == "'")
         | 
| 3063 | 
            -
                        return chain(stream, state, jsTokenString(ch));
         | 
| 3064 | 
            -
                    else if (/[\[\]{}\(\),;\:\.]/.test(ch))
         | 
| 3065 | 
            -
                        return ret(ch);
         | 
| 3066 | 
            -
                    else if (ch == "0" && stream.eat(/x/i)) {
         | 
| 3067 | 
            -
                        stream.eatWhile(/[\da-f]/i);
         | 
| 3068 | 
            -
                        return ret("number", "number");
         | 
| 3069 | 
            -
                    }
         | 
| 3070 | 
            -
                    else if (/\d/.test(ch)) {
         | 
| 3071 | 
            -
                        stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
         | 
| 3072 | 
            -
                        return ret("number", "number");
         | 
| 3073 | 
            -
                    }
         | 
| 3074 | 
            -
                    else if (ch == "/") {
         | 
| 3075 | 
            -
                        if (stream.eat("*")) {
         | 
| 3076 | 
            -
                            return chain(stream, state, jsTokenComment);
         | 
| 3077 | 
            -
                        }
         | 
| 3078 | 
            -
                        else if (stream.eat("/")) {
         | 
| 3079 | 
            -
                            stream.skipToEnd();
         | 
| 3080 | 
            -
                            return ret("comment", "comment");
         | 
| 3081 | 
            -
                        }
         | 
| 3082 | 
            -
                        else if (state.reAllowed) {
         | 
| 3083 | 
            -
                            nextUntilUnescaped(stream, "/");
         | 
| 3084 | 
            -
                            stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
         | 
| 3085 | 
            -
                            return ret("regexp", "string");
         | 
| 3086 | 
            -
                        }
         | 
| 3087 | 
            -
                        else {
         | 
| 3088 | 
            -
                            stream.eatWhile(isOperatorChar);
         | 
| 3089 | 
            -
                            return ret("operator", null, stream.current());
         | 
| 3090 | 
            -
                        }
         | 
| 3091 | 
            -
                    }
         | 
| 3092 | 
            -
                    else if (ch == "#") {
         | 
| 3093 | 
            -
                        stream.skipToEnd();
         | 
| 3094 | 
            -
                        return ret("error", "error");
         | 
| 3095 | 
            -
                    }
         | 
| 3096 | 
            -
                    else if (isOperatorChar.test(ch)) {
         | 
| 3097 | 
            -
                        stream.eatWhile(isOperatorChar);
         | 
| 3098 | 
            -
                        return ret("operator", null, stream.current());
         | 
| 3099 | 
            -
                    }
         | 
| 3100 | 
            -
                    else {
         | 
| 3101 | 
            -
                        stream.eatWhile(/[\w\$_]/);
         | 
| 3102 | 
            -
                        var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
         | 
| 3103 | 
            -
                        return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
         | 
| 3104 | 
            -
                            ret("variable", "variable", word);
         | 
| 3105 | 
            -
                    }
         | 
| 3106 | 
            -
                }
         | 
| 3107 | 
            -
             | 
| 3108 | 
            -
                function jsTokenString(quote) {
         | 
| 3109 | 
            -
                    return function(stream, state) {
         | 
| 3110 | 
            -
                        if (!nextUntilUnescaped(stream, quote))
         | 
| 3111 | 
            -
                            state.tokenize = jsTokenBase;
         | 
| 3112 | 
            -
                        return ret("string", "string");
         | 
| 3113 | 
            -
                    };
         | 
| 3114 | 
            -
                }
         | 
| 3115 | 
            -
             | 
| 3116 | 
            -
                function jsTokenComment(stream, state) {
         | 
| 3117 | 
            -
                    var maybeEnd = false, ch;
         | 
| 3118 | 
            -
                    while (ch = stream.next()) {
         | 
| 3119 | 
            -
                        if (ch == "/" && maybeEnd) {
         | 
| 3120 | 
            -
                            state.tokenize = jsTokenBase;
         | 
| 3121 | 
            -
                            break;
         | 
| 3122 | 
            -
                        }
         | 
| 3123 | 
            -
                        maybeEnd = (ch == "*");
         | 
| 3124 | 
            -
                    }
         | 
| 3125 | 
            -
                    return ret("comment", "comment");
         | 
| 3126 | 
            -
                }
         | 
| 3127 | 
            -
             | 
| 3128 | 
            -
                // Parser
         | 
| 3129 | 
            -
             | 
| 3130 | 
            -
                var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
         | 
| 3131 | 
            -
             | 
| 3132 | 
            -
                function JSLexical(indented, column, type, align, prev, info) {
         | 
| 3133 | 
            -
                    this.indented = indented;
         | 
| 3134 | 
            -
                    this.column = column;
         | 
| 3135 | 
            -
                    this.type = type;
         | 
| 3136 | 
            -
                    this.prev = prev;
         | 
| 3137 | 
            -
                    this.info = info;
         | 
| 3138 | 
            -
                    if (align != null) this.align = align;
         | 
| 3139 | 
            -
                }
         | 
| 3140 | 
            -
             | 
| 3141 | 
            -
                function inScope(state, varname) {
         | 
| 3142 | 
            -
                    for (var v = state.localVars; v; v = v.next)
         | 
| 3143 | 
            -
                        if (v.name == varname) return true;
         | 
| 3144 | 
            -
                }
         | 
| 3145 | 
            -
             | 
| 3146 | 
            -
                function parseJS(state, style, type, content, stream) {
         | 
| 3147 | 
            -
                    var cc = state.cc;
         | 
| 3148 | 
            -
                    // Communicate our context to the combinators.
         | 
| 3149 | 
            -
                    // (Less wasteful than consing up a hundred closures on every call.)
         | 
| 3150 | 
            -
                    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
         | 
| 3151 | 
            -
             | 
| 3152 | 
            -
                    if (!state.lexical.hasOwnProperty("align"))
         | 
| 3153 | 
            -
                        state.lexical.align = true;
         | 
| 3154 | 
            -
             | 
| 3155 | 
            -
                    while(true) {
         | 
| 3156 | 
            -
                        var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
         | 
| 3157 | 
            -
                        if (combinator(type, content)) {
         | 
| 3158 | 
            -
                            while(cc.length && cc[cc.length - 1].lex)
         | 
| 3159 | 
            -
                                cc.pop()();
         | 
| 3160 | 
            -
                            if (cx.marked) return cx.marked;
         | 
| 3161 | 
            -
                            if (type == "variable" && inScope(state, content)) return "variable-2";
         | 
| 3162 | 
            -
                            return style;
         | 
| 3163 | 
            -
                        }
         | 
| 3164 | 
            -
                    }
         | 
| 3165 | 
            -
                }
         | 
| 3166 | 
            -
             | 
| 3167 | 
            -
                // Combinator utils
         | 
| 3168 | 
            -
             | 
| 3169 | 
            -
                var cx = {state: null, column: null, marked: null, cc: null};
         | 
| 3170 | 
            -
                function pass() {
         | 
| 3171 | 
            -
                    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
         | 
| 3172 | 
            -
                }
         | 
| 3173 | 
            -
                function cont() {
         | 
| 3174 | 
            -
                    pass.apply(null, arguments);
         | 
| 3175 | 
            -
                    return true;
         | 
| 3176 | 
            -
                }
         | 
| 3177 | 
            -
                function register(varname) {
         | 
| 3178 | 
            -
                    var state = cx.state;
         | 
| 3179 | 
            -
                    if (state.context) {
         | 
| 3180 | 
            -
                        cx.marked = "def";
         | 
| 3181 | 
            -
                        for (var v = state.localVars; v; v = v.next)
         | 
| 3182 | 
            -
                            if (v.name == varname) return;
         | 
| 3183 | 
            -
                        state.localVars = {name: varname, next: state.localVars};
         | 
| 3184 | 
            -
                    }
         | 
| 3185 | 
            -
                }
         | 
| 3186 | 
            -
             | 
| 3187 | 
            -
                // Combinators
         | 
| 3188 | 
            -
             | 
| 3189 | 
            -
                var defaultVars = {name: "this", next: {name: "arguments"}};
         | 
| 3190 | 
            -
                function pushcontext() {
         | 
| 3191 | 
            -
                    if (!cx.state.context) cx.state.localVars = defaultVars;
         | 
| 3192 | 
            -
                    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
         | 
| 3193 | 
            -
                }
         | 
| 3194 | 
            -
                function popcontext() {
         | 
| 3195 | 
            -
                    cx.state.localVars = cx.state.context.vars;
         | 
| 3196 | 
            -
                    cx.state.context = cx.state.context.prev;
         | 
| 3197 | 
            -
                }
         | 
| 3198 | 
            -
                function pushlex(type, info) {
         | 
| 3199 | 
            -
                    var result = function() {
         | 
| 3200 | 
            -
                        var state = cx.state;
         | 
| 3201 | 
            -
                        state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
         | 
| 3202 | 
            -
                    };
         | 
| 3203 | 
            -
                    result.lex = true;
         | 
| 3204 | 
            -
                    return result;
         | 
| 3205 | 
            -
                }
         | 
| 3206 | 
            -
                function poplex() {
         | 
| 3207 | 
            -
                    var state = cx.state;
         | 
| 3208 | 
            -
                    if (state.lexical.prev) {
         | 
| 3209 | 
            -
                        if (state.lexical.type == ")")
         | 
| 3210 | 
            -
                            state.indented = state.lexical.indented;
         | 
| 3211 | 
            -
                        state.lexical = state.lexical.prev;
         | 
| 3212 | 
            -
                    }
         | 
| 3213 | 
            -
                }
         | 
| 3214 | 
            -
                poplex.lex = true;
         | 
| 3215 | 
            -
             | 
| 3216 | 
            -
                function expect(wanted) {
         | 
| 3217 | 
            -
                    return function expecting(type) {
         | 
| 3218 | 
            -
                        if (type == wanted) return cont();
         | 
| 3219 | 
            -
                        else if (wanted == ";") return pass();
         | 
| 3220 | 
            -
                        else return cont(arguments.callee);
         | 
| 3221 | 
            -
                    };
         | 
| 3222 | 
            -
                }
         | 
| 3223 | 
            -
             | 
| 3224 | 
            -
                function statement(type) {
         | 
| 3225 | 
            -
                    if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
         | 
| 3226 | 
            -
                    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
         | 
| 3227 | 
            -
                    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
         | 
| 3228 | 
            -
                    if (type == "{") return cont(pushlex("}"), block, poplex);
         | 
| 3229 | 
            -
                    if (type == ";") return cont();
         | 
| 3230 | 
            -
                    if (type == "function") return cont(functiondef);
         | 
| 3231 | 
            -
                    if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
         | 
| 3232 | 
            -
                        poplex, statement, poplex);
         | 
| 3233 | 
            -
                    if (type == "variable") return cont(pushlex("stat"), maybelabel);
         | 
| 3234 | 
            -
                    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
         | 
| 3235 | 
            -
                        block, poplex, poplex);
         | 
| 3236 | 
            -
                    if (type == "case") return cont(expression, expect(":"));
         | 
| 3237 | 
            -
                    if (type == "default") return cont(expect(":"));
         | 
| 3238 | 
            -
                    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
         | 
| 3239 | 
            -
                        statement, poplex, popcontext);
         | 
| 3240 | 
            -
                    return pass(pushlex("stat"), expression, expect(";"), poplex);
         | 
| 3241 | 
            -
                }
         | 
| 3242 | 
            -
                function expression(type) {
         | 
| 3243 | 
            -
                    if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
         | 
| 3244 | 
            -
                    if (type == "function") return cont(functiondef);
         | 
| 3245 | 
            -
                    if (type == "keyword c") return cont(maybeexpression);
         | 
| 3246 | 
            -
                    if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
         | 
| 3247 | 
            -
                    if (type == "operator") return cont(expression);
         | 
| 3248 | 
            -
                    if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
         | 
| 3249 | 
            -
                    if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
         | 
| 3250 | 
            -
                    return cont();
         | 
| 3251 | 
            -
                }
         | 
| 3252 | 
            -
                function maybeexpression(type) {
         | 
| 3253 | 
            -
                    if (type.match(/[;\}\)\],]/)) return pass();
         | 
| 3254 | 
            -
                    return pass(expression);
         | 
| 3255 | 
            -
                }
         | 
| 3256 | 
            -
             | 
| 3257 | 
            -
                function maybeoperator(type, value) {
         | 
| 3258 | 
            -
                    if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
         | 
| 3259 | 
            -
                    if (type == "operator") return cont(expression);
         | 
| 3260 | 
            -
                    if (type == ";") return;
         | 
| 3261 | 
            -
                    if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
         | 
| 3262 | 
            -
                    if (type == ".") return cont(property, maybeoperator);
         | 
| 3263 | 
            -
                    if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
         | 
| 3264 | 
            -
                }
         | 
| 3265 | 
            -
                function maybelabel(type) {
         | 
| 3266 | 
            -
                    if (type == ":") return cont(poplex, statement);
         | 
| 3267 | 
            -
                    return pass(maybeoperator, expect(";"), poplex);
         | 
| 3268 | 
            -
                }
         | 
| 3269 | 
            -
                function property(type) {
         | 
| 3270 | 
            -
                    if (type == "variable") {cx.marked = "property"; return cont();}
         | 
| 3271 | 
            -
                }
         | 
| 3272 | 
            -
                function objprop(type) {
         | 
| 3273 | 
            -
                    if (type == "variable") cx.marked = "property";
         | 
| 3274 | 
            -
                    if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
         | 
| 3275 | 
            -
                }
         | 
| 3276 | 
            -
                function commasep(what, end) {
         | 
| 3277 | 
            -
                    function proceed(type) {
         | 
| 3278 | 
            -
                        if (type == ",") return cont(what, proceed);
         | 
| 3279 | 
            -
                        if (type == end) return cont();
         | 
| 3280 | 
            -
                        return cont(expect(end));
         | 
| 3281 | 
            -
                    }
         | 
| 3282 | 
            -
                    return function commaSeparated(type) {
         | 
| 3283 | 
            -
                        if (type == end) return cont();
         | 
| 3284 | 
            -
                        else return pass(what, proceed);
         | 
| 3285 | 
            -
                    };
         | 
| 3286 | 
            -
                }
         | 
| 3287 | 
            -
                function block(type) {
         | 
| 3288 | 
            -
                    if (type == "}") return cont();
         | 
| 3289 | 
            -
                    return pass(statement, block);
         | 
| 3290 | 
            -
                }
         | 
| 3291 | 
            -
                function vardef1(type, value) {
         | 
| 3292 | 
            -
                    if (type == "variable"){register(value); return cont(vardef2);}
         | 
| 3293 | 
            -
                    return cont();
         | 
| 3294 | 
            -
                }
         | 
| 3295 | 
            -
                function vardef2(type, value) {
         | 
| 3296 | 
            -
                    if (value == "=") return cont(expression, vardef2);
         | 
| 3297 | 
            -
                    if (type == ",") return cont(vardef1);
         | 
| 3298 | 
            -
                }
         | 
| 3299 | 
            -
                function forspec1(type) {
         | 
| 3300 | 
            -
                    if (type == "var") return cont(vardef1, forspec2);
         | 
| 3301 | 
            -
                    if (type == ";") return pass(forspec2);
         | 
| 3302 | 
            -
                    if (type == "variable") return cont(formaybein);
         | 
| 3303 | 
            -
                    return pass(forspec2);
         | 
| 3304 | 
            -
                }
         | 
| 3305 | 
            -
                function formaybein(type, value) {
         | 
| 3306 | 
            -
                    if (value == "in") return cont(expression);
         | 
| 3307 | 
            -
                    return cont(maybeoperator, forspec2);
         | 
| 3308 | 
            -
                }
         | 
| 3309 | 
            -
                function forspec2(type, value) {
         | 
| 3310 | 
            -
                    if (type == ";") return cont(forspec3);
         | 
| 3311 | 
            -
                    if (value == "in") return cont(expression);
         | 
| 3312 | 
            -
                    return cont(expression, expect(";"), forspec3);
         | 
| 3313 | 
            -
                }
         | 
| 3314 | 
            -
                function forspec3(type) {
         | 
| 3315 | 
            -
                    if (type != ")") cont(expression);
         | 
| 3316 | 
            -
                }
         | 
| 3317 | 
            -
                function functiondef(type, value) {
         | 
| 3318 | 
            -
                    if (type == "variable") {register(value); return cont(functiondef);}
         | 
| 3319 | 
            -
                    if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
         | 
| 3320 | 
            -
                }
         | 
| 3321 | 
            -
                function funarg(type, value) {
         | 
| 3322 | 
            -
                    if (type == "variable") {register(value); return cont();}
         | 
| 3323 | 
            -
                }
         | 
| 3324 | 
            -
             | 
| 3325 | 
            -
                // Interface
         | 
| 3326 | 
            -
             | 
| 3327 | 
            -
                return {
         | 
| 3328 | 
            -
                    startState: function(basecolumn) {
         | 
| 3329 | 
            -
                        return {
         | 
| 3330 | 
            -
                            tokenize: jsTokenBase,
         | 
| 3331 | 
            -
                            reAllowed: true,
         | 
| 3332 | 
            -
                            kwAllowed: true,
         | 
| 3333 | 
            -
                            cc: [],
         | 
| 3334 | 
            -
                            lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
         | 
| 3335 | 
            -
                            localVars: null,
         | 
| 3336 | 
            -
                            context: null,
         | 
| 3337 | 
            -
                            indented: 0
         | 
| 3338 | 
            -
                        };
         | 
| 3339 | 
            -
                    },
         | 
| 3340 | 
            -
             | 
| 3341 | 
            -
                    token: function(stream, state) {
         | 
| 3342 | 
            -
                        if (stream.sol()) {
         | 
| 3343 | 
            -
                            if (!state.lexical.hasOwnProperty("align"))
         | 
| 3344 | 
            -
                                state.lexical.align = false;
         | 
| 3345 | 
            -
                            state.indented = stream.indentation();
         | 
| 3346 | 
            -
                        }
         | 
| 3347 | 
            -
                        if (stream.eatSpace()) return null;
         | 
| 3348 | 
            -
                        var style = state.tokenize(stream, state);
         | 
| 3349 | 
            -
                        if (type == "comment") return style;
         | 
| 3350 | 
            -
                        state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
         | 
| 3351 | 
            -
                        state.kwAllowed = type != '.';
         | 
| 3352 | 
            -
                        return parseJS(state, style, type, content, stream);
         | 
| 3353 | 
            -
                    },
         | 
| 3354 | 
            -
             | 
| 3355 | 
            -
                    indent: function(state, textAfter) {
         | 
| 3356 | 
            -
                        if (state.tokenize != jsTokenBase) return 0;
         | 
| 3357 | 
            -
                        var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
         | 
| 3358 | 
            -
                            type = lexical.type, closing = firstChar == type;
         | 
| 3359 | 
            -
                        if (type == "vardef") return lexical.indented + 4;
         | 
| 3360 | 
            -
                        else if (type == "form" && firstChar == "{") return lexical.indented;
         | 
| 3361 | 
            -
                        else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
         | 
| 3362 | 
            -
                        else if (lexical.info == "switch" && !closing)
         | 
| 3363 | 
            -
                            return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
         | 
| 3364 | 
            -
                        else if (lexical.align) return lexical.column + (closing ? 0 : 1);
         | 
| 3365 | 
            -
                        else return lexical.indented + (closing ? 0 : indentUnit);
         | 
| 3366 | 
            -
                    },
         | 
| 3367 | 
            -
             | 
| 3368 | 
            -
                    electricChars: ":{}"
         | 
| 3369 | 
            -
                };
         | 
| 3370 | 
            -
            });
         | 
| 3371 | 
            -
             | 
| 3372 | 
            -
            CodeMirror.defineMIME("text/javascript", "javascript");
         | 
| 3373 | 
            -
            CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
         | 
| 3374 | 
            -
             | 
| 3375 | 
            -
            CodeMirror.defineMode("css", function(config) {
         | 
| 3376 | 
            -
                var indentUnit = config.indentUnit, type;
         | 
| 3377 | 
            -
                function ret(style, tp) {type = tp; return style;}
         | 
| 3378 | 
            -
             | 
| 3379 | 
            -
                function tokenBase(stream, state) {
         | 
| 3380 | 
            -
                    var ch = stream.next();
         | 
| 3381 | 
            -
                    if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
         | 
| 3382 | 
            -
                    else if (ch == "/" && stream.eat("*")) {
         | 
| 3383 | 
            -
                        state.tokenize = tokenCComment;
         | 
| 3384 | 
            -
                        return tokenCComment(stream, state);
         | 
| 3385 | 
            -
                    }
         | 
| 3386 | 
            -
                    else if (ch == "<" && stream.eat("!")) {
         | 
| 3387 | 
            -
                        state.tokenize = tokenSGMLComment;
         | 
| 3388 | 
            -
                        return tokenSGMLComment(stream, state);
         | 
| 3389 | 
            -
                    }
         | 
| 3390 | 
            -
                    else if (ch == "=") ret(null, "compare");
         | 
| 3391 | 
            -
                    else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
         | 
| 3392 | 
            -
                    else if (ch == "\"" || ch == "'") {
         | 
| 3393 | 
            -
                        state.tokenize = tokenString(ch);
         | 
| 3394 | 
            -
                        return state.tokenize(stream, state);
         | 
| 3395 | 
            -
                    }
         | 
| 3396 | 
            -
                    else if (ch == "#") {
         | 
| 3397 | 
            -
                        stream.eatWhile(/[\w\\\-]/);
         | 
| 3398 | 
            -
                        return ret("atom", "hash");
         | 
| 3399 | 
            -
                    }
         | 
| 3400 | 
            -
                    else if (ch == "!") {
         | 
| 3401 | 
            -
                        stream.match(/^\s*\w*/);
         | 
| 3402 | 
            -
                        return ret("keyword", "important");
         | 
| 3403 | 
            -
                    }
         | 
| 3404 | 
            -
                    else if (/\d/.test(ch)) {
         | 
| 3405 | 
            -
                        stream.eatWhile(/[\w.%]/);
         | 
| 3406 | 
            -
                        return ret("number", "unit");
         | 
| 3407 | 
            -
                    }
         | 
| 3408 | 
            -
                    else if (/[,.+>*\/]/.test(ch)) {
         | 
| 3409 | 
            -
                        return ret(null, "select-op");
         | 
| 3410 | 
            -
                    }
         | 
| 3411 | 
            -
                    else if (/[;{}:\[\]]/.test(ch)) {
         | 
| 3412 | 
            -
                        return ret(null, ch);
         | 
| 3413 | 
            -
                    }
         | 
| 3414 | 
            -
                    else {
         | 
| 3415 | 
            -
                        stream.eatWhile(/[\w\\\-]/);
         | 
| 3416 | 
            -
                        return ret("variable", "variable");
         | 
| 3417 | 
            -
                    }
         | 
| 3418 | 
            -
                }
         | 
| 3419 | 
            -
             | 
| 3420 | 
            -
                function tokenCComment(stream, state) {
         | 
| 3421 | 
            -
                    var maybeEnd = false, ch;
         | 
| 3422 | 
            -
                    while ((ch = stream.next()) != null) {
         | 
| 3423 | 
            -
                        if (maybeEnd && ch == "/") {
         | 
| 3424 | 
            -
                            state.tokenize = tokenBase;
         | 
| 3425 | 
            -
                            break;
         | 
| 3426 | 
            -
                        }
         | 
| 3427 | 
            -
                        maybeEnd = (ch == "*");
         | 
| 3428 | 
            -
                    }
         | 
| 3429 | 
            -
                    return ret("comment", "comment");
         | 
| 3430 | 
            -
                }
         | 
| 3431 | 
            -
             | 
| 3432 | 
            -
                function tokenSGMLComment(stream, state) {
         | 
| 3433 | 
            -
                    var dashes = 0, ch;
         | 
| 3434 | 
            -
                    while ((ch = stream.next()) != null) {
         | 
| 3435 | 
            -
                        if (dashes >= 2 && ch == ">") {
         | 
| 3436 | 
            -
                            state.tokenize = tokenBase;
         | 
| 3437 | 
            -
                            break;
         | 
| 3438 | 
            -
                        }
         | 
| 3439 | 
            -
                        dashes = (ch == "-") ? dashes + 1 : 0;
         | 
| 3440 | 
            -
                    }
         | 
| 3441 | 
            -
                    return ret("comment", "comment");
         | 
| 3442 | 
            -
                }
         | 
| 3443 | 
            -
             | 
| 3444 | 
            -
                function tokenString(quote) {
         | 
| 3445 | 
            -
                    return function(stream, state) {
         | 
| 3446 | 
            -
                        var escaped = false, ch;
         | 
| 3447 | 
            -
                        while ((ch = stream.next()) != null) {
         | 
| 3448 | 
            -
                            if (ch == quote && !escaped)
         | 
| 3449 | 
            -
                                break;
         | 
| 3450 | 
            -
                            escaped = !escaped && ch == "\\";
         | 
| 3451 | 
            -
                        }
         | 
| 3452 | 
            -
                        if (!escaped) state.tokenize = tokenBase;
         | 
| 3453 | 
            -
                        return ret("string", "string");
         | 
| 3454 | 
            -
                    };
         | 
| 3455 | 
            -
                }
         | 
| 3456 | 
            -
             | 
| 3457 | 
            -
                return {
         | 
| 3458 | 
            -
                    startState: function(base) {
         | 
| 3459 | 
            -
                        return {tokenize: tokenBase,
         | 
| 3460 | 
            -
                            baseIndent: base || 0,
         | 
| 3461 | 
            -
                            stack: []};
         | 
| 3462 | 
            -
                    },
         | 
| 3463 | 
            -
             | 
| 3464 | 
            -
                    token: function(stream, state) {
         | 
| 3465 | 
            -
                        if (stream.eatSpace()) return null;
         | 
| 3466 | 
            -
                        var style = state.tokenize(stream, state);
         | 
| 3467 | 
            -
             | 
| 3468 | 
            -
                        var context = state.stack[state.stack.length-1];
         | 
| 3469 | 
            -
                        if (type == "hash" && context == "rule") style = "atom";
         | 
| 3470 | 
            -
                        else if (style == "variable") {
         | 
| 3471 | 
            -
                            if (context == "rule") style = "number";
         | 
| 3472 | 
            -
                            else if (!context || context == "@media{") style = "tag";
         | 
| 3473 | 
            -
                        }
         | 
| 3474 | 
            -
             | 
| 3475 | 
            -
                        if (context == "rule" && /^[\{\};]$/.test(type))
         | 
| 3476 | 
            -
                            state.stack.pop();
         | 
| 3477 | 
            -
                        if (type == "{") {
         | 
| 3478 | 
            -
                            if (context == "@media") state.stack[state.stack.length-1] = "@media{";
         | 
| 3479 | 
            -
                            else state.stack.push("{");
         | 
| 3480 | 
            -
                        }
         | 
| 3481 | 
            -
                        else if (type == "}") state.stack.pop();
         | 
| 3482 | 
            -
                        else if (type == "@media") state.stack.push("@media");
         | 
| 3483 | 
            -
                        else if (context == "{" && type != "comment") state.stack.push("rule");
         | 
| 3484 | 
            -
                        return style;
         | 
| 3485 | 
            -
                    },
         | 
| 3486 | 
            -
             | 
| 3487 | 
            -
                    indent: function(state, textAfter) {
         | 
| 3488 | 
            -
                        var n = state.stack.length;
         | 
| 3489 | 
            -
                        if (/^\}/.test(textAfter))
         | 
| 3490 | 
            -
                            n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
         | 
| 3491 | 
            -
                        return state.baseIndent + n * indentUnit;
         | 
| 3492 | 
            -
                    },
         | 
| 3493 | 
            -
             | 
| 3494 | 
            -
                    electricChars: "}"
         | 
| 3495 | 
            -
                };
         | 
| 3496 | 
            -
            });
         | 
| 3497 | 
            -
             | 
| 3498 | 
            -
            CodeMirror.defineMIME("text/css", "css");
         | 
| 3499 | 
            -
            CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
         | 
| 3500 | 
            -
                var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
         | 
| 3501 | 
            -
                var jsMode = CodeMirror.getMode(config, "javascript");
         | 
| 3502 | 
            -
                var cssMode = CodeMirror.getMode(config, "css");
         | 
| 3503 | 
            -
             | 
| 3504 | 
            -
                function html(stream, state) {
         | 
| 3505 | 
            -
                    var style = htmlMode.token(stream, state.htmlState);
         | 
| 3506 | 
            -
                    if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
         | 
| 3507 | 
            -
                        if (/^script$/i.test(state.htmlState.context.tagName)) {
         | 
| 3508 | 
            -
                            state.token = javascript;
         | 
| 3509 | 
            -
                            state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
         | 
| 3510 | 
            -
                            state.mode = "javascript";
         | 
| 3511 | 
            -
                        }
         | 
| 3512 | 
            -
                        else if (/^style$/i.test(state.htmlState.context.tagName)) {
         | 
| 3513 | 
            -
                            state.token = css;
         | 
| 3514 | 
            -
                            state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
         | 
| 3515 | 
            -
                            state.mode = "css";
         | 
| 3516 | 
            -
                        }
         | 
| 3517 | 
            -
                    }
         | 
| 3518 | 
            -
                    return style;
         | 
| 3519 | 
            -
                }
         | 
| 3520 | 
            -
                function maybeBackup(stream, pat, style) {
         | 
| 3521 | 
            -
                    var cur = stream.current();
         | 
| 3522 | 
            -
                    var close = cur.search(pat);
         | 
| 3523 | 
            -
                    if (close > -1) stream.backUp(cur.length - close);
         | 
| 3524 | 
            -
                    return style;
         | 
| 3525 | 
            -
                }
         | 
| 3526 | 
            -
                function javascript(stream, state) {
         | 
| 3527 | 
            -
                    if (stream.match(/^<\/\s*script\s*>/i, false)) {
         | 
| 3528 | 
            -
                        state.token = html;
         | 
| 3529 | 
            -
                        state.curState = null;
         | 
| 3530 | 
            -
                        state.mode = "html";
         | 
| 3531 | 
            -
                        return html(stream, state);
         | 
| 3532 | 
            -
                    }
         | 
| 3533 | 
            -
                    return maybeBackup(stream, /<\/\s*script\s*>/,
         | 
| 3534 | 
            -
                        jsMode.token(stream, state.localState));
         | 
| 3535 | 
            -
                }
         | 
| 3536 | 
            -
                function css(stream, state) {
         | 
| 3537 | 
            -
                    if (stream.match(/^<\/\s*style\s*>/i, false)) {
         | 
| 3538 | 
            -
                        state.token = html;
         | 
| 3539 | 
            -
                        state.localState = null;
         | 
| 3540 | 
            -
                        state.mode = "html";
         | 
| 3541 | 
            -
                        return html(stream, state);
         | 
| 3542 | 
            -
                    }
         | 
| 3543 | 
            -
                    return maybeBackup(stream, /<\/\s*style\s*>/,
         | 
| 3544 | 
            -
                        cssMode.token(stream, state.localState));
         | 
| 3545 | 
            -
                }
         | 
| 3546 | 
            -
             | 
| 3547 | 
            -
                return {
         | 
| 3548 | 
            -
                    startState: function() {
         | 
| 3549 | 
            -
                        var state = htmlMode.startState();
         | 
| 3550 | 
            -
                        return {token: html, localState: null, mode: "html", htmlState: state};
         | 
| 3551 | 
            -
                    },
         | 
| 3552 | 
            -
             | 
| 3553 | 
            -
                    copyState: function(state) {
         | 
| 3554 | 
            -
                        if (state.localState)
         | 
| 3555 | 
            -
                            var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
         | 
| 3556 | 
            -
                        return {token: state.token, localState: local, mode: state.mode,
         | 
| 3557 | 
            -
                            htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
         | 
| 3558 | 
            -
                    },
         | 
| 3559 | 
            -
             | 
| 3560 | 
            -
                    token: function(stream, state) {
         | 
| 3561 | 
            -
                        return state.token(stream, state);
         | 
| 3562 | 
            -
                    },
         | 
| 3563 | 
            -
             | 
| 3564 | 
            -
                    indent: function(state, textAfter) {
         | 
| 3565 | 
            -
                        if (state.token == html || /^\s*<\//.test(textAfter))
         | 
| 3566 | 
            -
                            return htmlMode.indent(state.htmlState, textAfter);
         | 
| 3567 | 
            -
                        else if (state.token == javascript)
         | 
| 3568 | 
            -
                            return jsMode.indent(state.localState, textAfter);
         | 
| 3569 | 
            -
                        else
         | 
| 3570 | 
            -
                            return cssMode.indent(state.localState, textAfter);
         | 
| 3571 | 
            -
                    },
         | 
| 3572 | 
            -
             | 
| 3573 | 
            -
                    compareStates: function(a, b) {
         | 
| 3574 | 
            -
                        return htmlMode.compareStates(a.htmlState, b.htmlState);
         | 
| 3575 | 
            -
                    },
         | 
| 3576 | 
            -
             | 
| 3577 | 
            -
                    electricChars: "/{}:"
         | 
| 3578 | 
            -
                }
         | 
| 3579 | 
            -
            });
         | 
| 3580 | 
            -
             | 
| 3581 | 
            -
            CodeMirror.defineMIME("text/html", "htmlmixed");
         | 
| 1 | 
            +
            /*! UEditorPlus v2.0.0*/
         | 
| 2 | 
            +
            var CodeMirror=function(){function a(f,j){function r(a){return a>=0&&a<Yb.size}function u(a){return m(Yb,a)}function A(a,b){hc=!0;for(var c=b-a.height,d=a;d;d=d.parent)d.height+=c}function B(a){var b={line:0,ch:0};ga(b,{line:Yb.size-1,ch:u(Yb.size-1).text.length},X(a),b,b),bc=!0}function M(a){var b=[];return Yb.iter(0,Yb.size,function(a){b.push(a.text)}),b.join("\n")}function N(a){function b(a){var c=pb(a,!0);if(c&&!E(c,g)){Vb||ea(),g=c,Fa(d,c),bc=!1;var e=ya();(c.line>=e.to||c.line<e.from)&&(f=setTimeout(Ab(function(){b(a)}),150))}}Ea(a.shiftKey);for(var c=w(a);c!=Fb;c=c.parentNode)if(c.parentNode==Jb&&c!=Kb)return;for(var c=w(a);c!=Fb;c=c.parentNode)if(c.parentNode==Mb)return Bb.onGutterClick&&Bb.onGutterClick(vc,J(Mb.childNodes,c)+oc,a),t(a);var d=pb(a);switch(x(a)){case 3:return void(S&&!L&&qb(a));case 2:return void(d&&Ia(d.line,d.ch,!0))}if(!d)return void(w(a)==Ib&&t(a));Vb||ea();var e=+new Date;if(_b&&_b.time>e-400&&E(_b.pos,d))return t(a),setTimeout(ua,20),Qa(d.line);if($b&&$b.time>e-400&&E($b.pos,d))return _b={time:e,pos:d},t(a),Pa(d);$b={time:e,pos:d};var f,g=d;if(R&&!E(lc.from,lc.to)&&!F(d,lc.from)&&!F(lc.to,d)){U&&(Nb.draggable=!0);var h=y(Eb,"mouseup",Ab(function(b){U&&(Nb.draggable=!1),ac=!1,h(),Math.abs(a.clientX-b.clientX)+Math.abs(a.clientY-b.clientY)<10&&(t(b),Ia(d.line,d.ch,!0),ua())}),!0);return void(ac=!0)}t(a),Ia(d.line,d.ch,!0);var i=y(Eb,"mousemove",Ab(function(a){clearTimeout(f),t(a),b(a)}),!0),h=y(Eb,"mouseup",Ab(function(a){clearTimeout(f);var b=pb(a);b&&Fa(d,b),t(a),ua(),bc=!0,i(),h()}),!0)}function V(a){for(var b=w(a);b!=Fb;b=b.parentNode)if(b.parentNode==Mb)return t(a);var c=pb(a);c&&(_b={time:+new Date,pos:c},t(a),Pa(c))}function $(a){function b(a,b){var d=new FileReader;d.onload=function(){f[b]=d.result,++g==e&&(c=Ka(c),Ab(function(){var a=la(f.join(""),c,c);Fa(c,a)})())},d.readAsText(a)}a.preventDefault();var c=pb(a,!0),d=a.dataTransfer.files;if(c&&!Bb.readOnly)if(d&&d.length&&window.FileReader&&window.File)for(var e=d.length,f=Array(e),g=0,h=0;h<e;++h)b(d[h],h);else try{var f=a.dataTransfer.getData("Text");if(f){var i=la(f,c,c),j=lc.from,k=lc.to;Fa(c,i),ac&&la("",j,k),ua()}}catch(a){}}function _(a){var b=pa();H(b),a.dataTransfer.setDragImage(W,0,0),a.dataTransfer.setData("Text",b)}function aa(a){var d,e,f=Z[a.keyCode],g=Q[Bb.keyMap].auto;if(null==f||a.altGraphKey)return g&&(Bb.keyMap=g),null;if(a.altKey&&(f="Alt-"+f),a.ctrlKey&&(f="Ctrl-"+f),a.metaKey&&(f="Cmd-"+f),a.shiftKey&&(d=b("Shift-"+f,Bb.extraKeys,Bb.keyMap))?e=!0:d=b(f,Bb.extraKeys,Bb.keyMap),"string"==typeof d&&(d=P.propertyIsEnumerable(d)?P[d]:null),!g||!d&&c(a)||(Bb.keyMap=g),!d)return!1;if(e){var h=Zb;Zb=null,d(vc),Zb=h}else d(vc);return t(a),!0}function ba(a){Vb||ea();var b=a.keyCode;if(T&&27==b&&(a.returnValue=!1),Ea(16==b||a.shiftKey),!Bb.onKeyEvent||!Bb.onKeyEvent(vc,s(a))){var c=aa(a);window.opera&&(wc=c?a.keyCode:null,!c&&(L?a.metaKey:a.ctrlKey)&&88==a.keyCode&&ma(""))}}function ca(a){if(window.opera&&a.keyCode==wc)return wc=null,void t(a);if((!Bb.onKeyEvent||!Bb.onKeyEvent(vc,s(a)))&&(!window.opera||a.which||!aa(a))){if(Bb.electricChars&&Tb.electricChars){var b=String.fromCharCode(null==a.charCode?a.keyCode:a.charCode);Tb.electricChars.indexOf(b)>-1&&setTimeout(Ab(function(){Sa(lc.to.line,"smart")}),75)}ra()}}function da(a){Bb.onKeyEvent&&Bb.onKeyEvent(vc,s(a))||16==a.keyCode&&(Zb=null)}function ea(){Bb.readOnly||(Vb||(Bb.onFocus&&Bb.onFocus(vc),Vb=!0,Fb.className.search(/\bCodeMirror-focused\b/)==-1&&(Fb.className+=" CodeMirror-focused"),gc||ta(!0)),qa(),rb())}function fa(){Vb&&(Bb.onBlur&&Bb.onBlur(vc),Vb=!1,Fb.className=Fb.className.replace(" CodeMirror-focused","")),clearInterval(Sb),setTimeout(function(){Vb||(Zb=null)},150)}function ga(a,b,c,d,e){if(tc){var f=[];for(Yb.iter(a.line,b.line+1,function(a){f.push(a.text)}),tc.addChange(a.line,c.length,f);tc.done.length>Bb.undoDepth;)tc.done.shift()}ka(a,b,c,d,e)}function ha(a,b){var c=a.pop();if(c){var d=[],e=c.start+c.added;Yb.iter(c.start,e,function(a){d.push(a.text)}),b.push({start:c.start,added:c.old.length,old:d});var f=Ka({line:c.start+c.old.length-1,ch:I(d[d.length-1],c.old[c.old.length-1])});ka({line:c.start,ch:0},{line:e-1,ch:u(e-1).text.length},c.old,f,f),bc=!0}}function ia(){ha(tc.done,tc.undone)}function ja(){ha(tc.undone,tc.done)}function ka(a,b,c,d,e){function f(a){return a<=Math.min(b.line,b.line+s)?a:a+s}var g=!1,h=rc.length;Bb.lineWrapping||Yb.iter(a.line,b.line,function(a){if(a.text.length==h)return g=!0,!0}),(a.line!=b.line||c.length>1)&&(hc=!0);var j=b.line-a.line,k=u(a.line),l=u(b.line);if(0==a.ch&&0==b.ch&&""==c[c.length-1]){var m=[],n=null;a.line?(n=u(a.line-1),n.fixMarkEnds(l)):l.fixMarkStarts();for(var o=0,p=c.length-1;o<p;++o)m.push(i.inheritMarks(c[o],n));j&&Yb.remove(a.line,j,ic),m.length&&Yb.insert(a.line,m)}else if(k==l)if(1==c.length)k.replace(a.ch,b.ch,c[0]);else{l=k.split(b.ch,c[c.length-1]),k.replace(a.ch,null,c[0]),k.fixMarkEnds(l);for(var m=[],o=1,p=c.length-1;o<p;++o)m.push(i.inheritMarks(c[o],k));m.push(l),Yb.insert(a.line+1,m)}else if(1==c.length)k.replace(a.ch,null,c[0]),l.replace(null,b.ch,""),k.append(l),Yb.remove(a.line+1,j,ic);else{var m=[];k.replace(a.ch,null,c[0]),l.replace(null,b.ch,c[c.length-1]),k.fixMarkEnds(l);for(var o=1,p=c.length-1;o<p;++o)m.push(i.inheritMarks(c[o],k));j>1&&Yb.remove(a.line+1,j-1,ic),Yb.insert(a.line+1,m)}if(Bb.lineWrapping){var q=Ib.clientWidth/mb()-3;Yb.iter(a.line,a.line+c.length,function(a){if(!a.hidden){var b=Math.ceil(a.text.length/q)||1;b!=a.height&&A(a,b)}})}else Yb.iter(a.line,o+c.length,function(a){var b=a.text;b.length>h&&(rc=b,h=b.length,kc=null,g=!1)}),g&&(h=0,rc="",kc=null,Yb.iter(0,Yb.size,function(a){var b=a.text;b.length>h&&(h=b.length,rc=b)}));for(var r=[],s=c.length-j-1,o=0,t=Ub.length;o<t;++o){var v=Ub[o];v<a.line?r.push(v):v>b.line&&r.push(v+s)}var w=a.line+Math.min(c.length,500);vb(a.line,w),r.push(w),Ub=r,xb(100),dc.push({from:a.line,to:b.line+1,diff:s});var x={from:a,to:b,text:c};if(ec){for(var y=ec;y.next;y=y.next);y.next=x}else ec=x;Ga(d,e,f(lc.from.line),f(lc.to.line)),Jb.style.height=Yb.height*lb()+2*nb()+"px"}function la(a,b,c){function d(d){if(F(d,b))return d;if(!F(c,d))return e;var f=d.line+a.length-(c.line-b.line)-1,g=d.ch;return d.line==c.line&&(g+=a[a.length-1].length-(c.ch-(c.line==b.line?b.ch:0))),{line:f,ch:g}}b=Ka(b),c=c?Ka(c):b,a=X(a);var e;return na(a,b,c,function(a){return e=a,{from:d(lc.from),to:d(lc.to)}}),e}function ma(a,b){na(X(a),lc.from,lc.to,function(a){return"end"==b?{from:a,to:a}:"start"==b?{from:lc.from,to:lc.from}:{from:lc.from,to:a}})}function na(a,b,c,d){var e=1==a.length?a[0].length+b.ch:a[a.length-1].length,f=d({line:b.line+a.length-1,ch:e});ga(b,c,a,f.from,f.to)}function oa(a,b){var c=a.line,d=b.line;if(c==d)return u(c).text.slice(a.ch,b.ch);var e=[u(c).text.slice(a.ch)];return Yb.iter(c+1,d,function(a){e.push(a.text)}),e.push(u(d).text.slice(0,b.ch)),e.join("\n")}function pa(){return oa(lc.from,lc.to)}function qa(){xc||Wb.set(Bb.pollInterval,function(){yb(),sa(),Vb&&qa(),zb()})}function ra(){function a(){yb();var c=sa();c||b?(xc=!1,qa()):(b=!0,Wb.set(60,a)),zb()}var b=!1;xc=!0,Wb.set(20,a)}function sa(){if(gc||!Vb||Y(Hb))return!1;var a=Hb.value;if(a==yc)return!1;Zb=null;for(var b=0,c=Math.min(yc.length,a.length);b<c&&yc[b]==a[b];)++b;return b<yc.length?lc.from={line:lc.from.line,ch:lc.from.ch-(yc.length-b)}:mc&&E(lc.from,lc.to)&&(lc.to={line:lc.to.line,ch:Math.min(u(lc.to.line).text.length,lc.to.ch+(a.length-b))}),ma(a.slice(b),"end"),yc=a,!0}function ta(a){E(lc.from,lc.to)?a&&(yc=Hb.value=""):(yc="",Hb.value=pa(),Hb.select())}function ua(){Bb.readOnly||Hb.focus()}function va(){if(Pb.getBoundingClientRect){var a=Pb.getBoundingClientRect();if(!T||a.top!=a.bottom){var b=window.innerHeight||Math.max(document.body.offsetHeight,document.documentElement.offsetHeight);(a.top<0||a.bottom>b)&&Pb.scrollIntoView()}}}function wa(){var a=ib(lc.inverted?lc.from:lc.to),b=Bb.lineWrapping?Math.min(a.x,Nb.offsetWidth):a.x;return xa(b,a.y,b,a.yBot)}function xa(a,b,c,d){var e=ob(),f=nb(),g=lb();b+=f,d+=f,a+=e,c+=e;var h=Ib.clientHeight,i=Ib.scrollTop,j=!1,k=!0;b<i?(Ib.scrollTop=Math.max(0,b-2*g),j=!0):d>i+h&&(Ib.scrollTop=d+g-h,j=!0);var l=Ib.clientWidth,m=Ib.scrollLeft,n=Bb.fixedGutter?Lb.clientWidth:0;return a<m+n?(a<50&&(a=0),Ib.scrollLeft=Math.max(0,a-10-n),j=!0):c>l+m-3&&(Ib.scrollLeft=c+10-l,j=!0,c>Jb.clientWidth&&(k=!1)),j&&Bb.onScroll&&Bb.onScroll(vc),k}function ya(){var a=lb(),b=Ib.scrollTop-nb(),c=Math.max(0,Math.floor(b/a)),d=Math.ceil((b+Ib.clientHeight)/a);return{from:o(Yb,c),to:o(Yb,d)}}function za(a,b){if(!Ib.clientWidth)return void(oc=pc=nc=0);var c=ya();if(!(a!==!0&&0==a.length&&c.from>=oc&&c.to<=pc)){var d=Math.max(c.from-100,0),e=Math.min(Yb.size,c.to+100);oc<d&&d-oc<20&&(d=oc),pc>e&&pc-e<20&&(e=Math.min(Yb.size,pc));for(var f=a===!0?[]:Aa([{from:oc,to:pc,domStart:0}],a),g=0,h=0;h<f.length;++h){var i=f[h];i.from<d&&(i.domStart+=d-i.from,i.from=d),i.to>e&&(i.to=e),i.from>=i.to?f.splice(h--,1):g+=i.to-i.from}if(g!=e-d){f.sort(function(a,b){return a.domStart-b.domStart});var j=lb(),k=Lb.style.display;Qb.style.display=Lb.style.display="none",Ba(d,e,f),Qb.style.display="";var l=d!=oc||e!=pc||qc!=Ib.clientHeight+j;if(l&&(qc=Ib.clientHeight+j),oc=d,pc=e,nc=p(Yb,d),Kb.style.top=nc*j+"px",Jb.style.height=Yb.height*j+2*nb()+"px",Qb.childNodes.length!=pc-oc)throw new Error("BAD PATCH! "+JSON.stringify(f)+" size="+(pc-oc)+" nodes="+Qb.childNodes.length);if(Bb.lineWrapping){kc=Ib.clientWidth;var m=Qb.firstChild;Yb.iter(oc,pc,function(a){if(!a.hidden){var b=Math.round(m.offsetHeight/j)||1;a.height!=b&&(A(a,b),hc=!0)}m=m.nextSibling})}else null==kc&&(kc=gb(rc)),kc>Ib.clientWidth?(Nb.style.width=kc+"px",Jb.style.width="",Jb.style.width=Ib.scrollWidth+"px"):Nb.style.width=Jb.style.width="";return Lb.style.display=k,(l||hc)&&Ca(),Da(),!b&&Bb.onUpdate&&Bb.onUpdate(vc),!0}}}function Aa(a,b){for(var c=0,d=b.length||0;c<d;++c){for(var e=b[c],f=[],g=e.diff||0,h=0,i=a.length;h<i;++h){var j=a[h];e.to<=j.from&&e.diff?f.push({from:j.from+g,to:j.to+g,domStart:j.domStart}):e.to<=j.from||e.from>=j.to?f.push(j):(e.from>j.from&&f.push({from:j.from,to:e.from,domStart:j.domStart}),e.to<j.to&&f.push({from:e.to+g,to:j.to+g,domStart:j.domStart+(e.to-j.from)}))}a=f}return a}function Ba(a,b,c){function d(a){var b=a.nextSibling;return a.parentNode.removeChild(a),b}if(c.length){for(var e=0,f=Qb.firstChild,g=0;g<c.length;++g){for(var h=c[g];h.domStart>e;)f=d(f),e++;for(var i=0,j=h.to-h.from;i<j;++i)f=f.nextSibling,e++}for(;f;)f=d(f)}else Qb.innerHTML="";var k=c.shift(),f=Qb.firstChild,i=a,l=lc.from.line,m=lc.to.line,n=l<a&&m>=a,o=Eb.createElement("div");Yb.iter(a,b,function(a){var b=null,d=null;n?(b=0,m==i&&(n=!1,d=lc.to.ch)):l==i&&(m==i?(b=lc.from.ch,d=lc.to.ch):(n=!0,b=lc.from.ch)),k&&k.to==i&&(k=c.shift()),!k||k.from>i?(a.hidden?o.innerHTML="<pre></pre>":o.innerHTML=a.getHTML(b,d,!0,sc),Qb.insertBefore(o.firstChild,f)):f=f.nextSibling,++i})}function Ca(){if(Bb.gutter||Bb.lineNumbers){var a=Kb.offsetHeight,b=Ib.clientHeight;Lb.style.height=(a-b<2?b:a)+"px";var c=[],d=oc;Yb.iter(oc,Math.max(pc,oc+1),function(a){if(a.hidden)c.push("<pre></pre>");else{var b=a.gutterMarker,e=Bb.lineNumbers?d+Bb.firstLineNumber:null;b&&b.text?e=b.text.replace("%N%",null!=e?e:""):null==e&&(e=" "),c.push(b&&b.style?'<pre class="'+b.style+'">':"<pre>",e);for(var f=1;f<a.height;++f)c.push("<br/> ");c.push("</pre>")}++d}),Lb.style.display="none",Mb.innerHTML=c.join("");for(var e=String(Yb.size).length,f=Mb.firstChild,g=D(f),h="";g.length+h.length<e;)h+=" ";h&&f.insertBefore(Eb.createTextNode(h),f.firstChild),Lb.style.display="",Nb.style.marginLeft=Lb.offsetWidth+"px",hc=!1}}function Da(){var a=lc.inverted?lc.from:lc.to,b=(lb(),ib(a,!0)),c=C(Fb),d=C(Qb);Gb.style.top=b.y+d.top-c.top+"px",Gb.style.left=b.x+d.left-c.left+"px",E(lc.from,lc.to)?(Pb.style.top=b.y+"px",Pb.style.left=(Bb.lineWrapping?Math.min(b.x,Nb.offsetWidth):b.x)+"px",Pb.style.display=""):Pb.style.display="none"}function Ea(a){Zb=a?Zb||(lc.inverted?lc.to:lc.from):null}function Fa(a,b){var c=Zb&&Ka(Zb);c&&(F(c,a)?a=c:F(b,c)&&(b=c)),Ga(a,b),cc=!0}function Ga(a,b,c,d){if(zc=null,null==c&&(c=lc.from.line,d=lc.to.line),!E(lc.from,a)||!E(lc.to,b)){if(F(b,a)){var e=b;b=a,a=e}a.line!=c&&(a=Ha(a,c,lc.from.ch)),b.line!=d&&(b=Ha(b,d,lc.to.ch)),E(a,b)?lc.inverted=!1:E(a,lc.to)?lc.inverted=!1:E(b,lc.from)&&(lc.inverted=!0),E(a,b)?E(lc.from,lc.to)||dc.push({from:c,to:d+1}):E(lc.from,lc.to)?dc.push({from:a.line,to:b.line+1}):(E(a,lc.from)||(a.line<c?dc.push({from:a.line,to:Math.min(b.line,c)+1}):dc.push({from:c,to:Math.min(d,a.line)+1})),E(b,lc.to)||(b.line<d?dc.push({from:Math.max(c,a.line),to:d+1}):dc.push({from:Math.max(a.line,d),to:b.line+1}))),lc.from=a,lc.to=b,fc=!0}}function Ha(a,b,c){function d(b){for(var d=a.line+b,e=1==b?Yb.size:-1;d!=e;){var f=u(d);if(!f.hidden){var g=a.ch;return(g>c||g>f.text.length)&&(g=f.text.length),{line:d,ch:g}}d+=b}}var e=u(a.line);return e.hidden?a.line>=b?d(1)||d(-1):d(-1)||d(1):a}function Ia(a,b,c){var d=Ka({line:a,ch:b||0});(c?Fa:Ga)(d,d)}function Ja(a){return Math.max(0,Math.min(a,Yb.size-1))}function Ka(a){if(a.line<0)return{line:0,ch:0};if(a.line>=Yb.size)return{line:Yb.size-1,ch:u(Yb.size-1).text.length};var b=a.ch,c=u(a.line).text.length;return null==b||b>c?{line:a.line,ch:c}:b<0?{line:a.line,ch:0}:a}function La(a,b){function c(){for(var b=f+a,c=a<0?-1:Yb.size;b!=c;b+=a){var d=u(b);if(!d.hidden)return f=b,h=d,!0}}function d(b){if(g==(a<0?0:h.text.length)){if(b||!c())return!1;g=a<0?h.text.length:0}else g+=a;return!0}var e=lc.inverted?lc.from:lc.to,f=e.line,g=e.ch,h=u(f);if("char"==b)d();else if("column"==b)d(!0);else if("word"==b)for(var i=!1;!(a<0)||d();){if(K(h.text.charAt(g)))i=!0;else if(i){a<0&&(a=1,d());break}if(a>0&&!d())break}return{line:f,ch:g}}function Ma(a,b){var c=a<0?lc.from:lc.to;(Zb||E(lc.from,lc.to))&&(c=La(a,b)),Ia(c.line,c.ch,!0)}function Na(a,b){E(lc.from,lc.to)?a<0?la("",La(a,b),lc.to):la("",lc.from,La(a,b)):la("",lc.from,lc.to),cc=!0}function Oa(a,b){var c=0,d=ib(lc.inverted?lc.from:lc.to,!0);null!=zc&&(d.x=zc),"page"==b?c=Ib.clientHeight:"line"==b&&(c=lb());var e=jb(d.x,d.y+c*a+2);Ia(e.line,e.ch,!0),zc=d.x}function Pa(a){for(var b=u(a.line).text,c=a.ch,d=a.ch;c>0&&K(b.charAt(c-1));)--c;for(;d<b.length&&K(b.charAt(d));)++d;Fa({line:a.line,ch:c},{line:a.line,ch:d})}function Qa(a){Fa({line:a,ch:0},{line:a,ch:u(a).text.length})}function Ra(a){if(E(lc.from,lc.to))return Sa(lc.from.line,a);for(var b=lc.to.line-(lc.to.ch?0:1),c=lc.from.line;c<=b;++c)Sa(c,a)}function Sa(a,b){if(b||(b="add"),"smart"==b)if(Tb.indent)var c=ub(a);else b="prev";var d,e=u(a),f=e.indentation(Bb.tabSize),g=e.text.match(/^\s*/)[0];"prev"==b?d=a?u(a-1).indentation(Bb.tabSize):0:"smart"==b?d=Tb.indent(c,e.text.slice(g.length),e.text):"add"==b?d=f+Bb.indentUnit:"subtract"==b&&(d=f-Bb.indentUnit),d=Math.max(0,d);var h=d-f;if(h){var i="",j=0;if(Bb.indentWithTabs)for(var k=Math.floor(d/Bb.tabSize);k;--k)j+=Bb.tabSize,i+="\t";for(;j<d;)++j,i+=" "}else{if(lc.from.line!=a&&lc.to.line!=a)return;var i=g}la(i,{line:a,ch:0},{line:a,ch:g.length})}function Ta(){Tb=a.getMode(Bb,Bb.mode),Yb.iter(0,Yb.size,function(a){a.stateAfter=null}),Ub=[0],xb()}function Ua(){var a=Bb.gutter||Bb.lineNumbers;Lb.style.display=a?"":"none",a?hc=!0:Qb.parentNode.style.marginLeft=0}function Va(a,b){if(Bb.lineWrapping){Fb.className+=" CodeMirror-wrap";var c=Ib.clientWidth/mb()-3;Yb.iter(0,Yb.size,function(a){if(!a.hidden){var b=Math.ceil(a.text.length/c)||1;1!=b&&A(a,b)}}),Nb.style.width=Jb.style.width=""}else Fb.className=Fb.className.replace(" CodeMirror-wrap",""),kc=null,rc="",Yb.iter(0,Yb.size,function(a){1==a.height||a.hidden||A(a,1),a.text.length>rc.length&&(rc=a.text)});dc.push({from:0,to:Yb.size})}function Wa(){for(var a='<span class="cm-tab">',b=0;b<Bb.tabSize;++b)a+=" ";return a+"</span>"}function Xa(){sc=Wa(),za(!0)}function Ya(){Ib.className=Ib.className.replace(/\s*cm-s-\w+/g,"")+Bb.theme.replace(/(^|\s)\s*/g," cm-s-")}function Za(){this.set=[]}function $a(a,b,c){function d(a,b,c,d){u(a).addMark(new g(b,c,d,e.set))}a=Ka(a),b=Ka(b);var e=new Za;if(a.line==b.line)d(a.line,a.ch,b.ch,c);else{d(a.line,a.ch,null,c);for(var f=a.line+1,h=b.line;f<h;++f)d(f,null,null,c);d(b.line,null,b.ch,c)}return dc.push({from:a.line,to:b.line+1}),e}function _a(a){a=Ka(a);var b=new h(a.ch);return u(a.line).addMark(b),b}function ab(a,b,c){return"number"==typeof a&&(a=u(Ja(a))),a.gutterMarker={text:b,style:c},hc=!0,a}function bb(a){"number"==typeof a&&(a=u(Ja(a))),a.gutterMarker=null,hc=!0}function cb(a,b){var c=a,d=a;return"number"==typeof a?d=u(Ja(a)):c=n(a),null==c?null:b(d,c)?(dc.push({from:c,to:c+1}),d):null}function db(a,b){return cb(a,function(a){if(a.className!=b)return a.className=b,!0})}function eb(a,b){return cb(a,function(a,c){if(a.hidden!=b)return a.hidden=b,A(a,b?0:1),!b||lc.from.line!=c&&lc.to.line!=c||Ga(Ha(lc.from,lc.from.line,lc.from.ch),Ha(lc.to,lc.to.line,lc.to.ch)),hc=!0})}function fb(a){if("number"==typeof a){if(!r(a))return null;var b=a;if(a=u(a),!a)return null}else{var b=n(a);if(null==b)return null}var c=a.gutterMarker;return{line:b,handle:a,text:a.text,markerText:c&&c.text,markerClass:c&&c.style,lineClass:a.className}}function gb(a){return Ob.innerHTML="<pre><span>x</span></pre>",Ob.firstChild.firstChild.firstChild.nodeValue=a,Ob.firstChild.firstChild.offsetWidth||10}function hb(a,b){var c="";if(Bb.lineWrapping){var d=a.text.indexOf(" ",b+2);c=H(a.text.slice(b+1,d<0?a.text.length:d+(T?5:0)))}Ob.innerHTML="<pre>"+a.getHTML(null,null,!1,sc,b)+'<span id="CodeMirror-temp-'+Ec+'">'+H(a.text.charAt(b)||" ")+"</span>"+c+"</pre>";var e=document.getElementById("CodeMirror-temp-"+Ec),f=e.offsetTop,g=e.offsetLeft;if(T&&b&&0==f&&0==g){var h=document.createElement("span");h.innerHTML="x",e.parentNode.insertBefore(h,e.nextSibling),f=h.offsetTop}return{top:f,left:g}}function ib(a,b){var c,d=lb(),e=d*(p(Yb,a.line)-(b?nc:0));if(0==a.ch)c=0;else{var f=hb(u(a.line),a.ch);c=f.left,Bb.lineWrapping&&(e+=Math.max(0,f.top))}return{x:c,y:e,yBot:e+d}}function jb(a,b){function c(a){var b=hb(h,a);if(j){var c=Math.round(b.top/d);return Math.max(0,b.left+(c-k)*Ib.clientWidth)}return b.left}b<0&&(b=0);var d=lb(),e=mb(),f=nc+Math.floor(b/d),g=o(Yb,f);if(g>=Yb.size)return{line:Yb.size-1,ch:u(Yb.size-1).text.length};var h=u(g),i=h.text,j=Bb.lineWrapping,k=j?f-p(Yb,g):0;if(a<=0&&0==k)return{line:g,ch:0};for(var l,m=0,n=0,q=i.length,r=Math.min(q,Math.ceil((a+k*Ib.clientWidth*.9)/e));;){var s=c(r);if(!(s<=a&&r<q)){l=s,q=r;break}r=Math.min(q,Math.ceil(1.2*r))}if(a>l)return{line:g,ch:q};for(r=Math.floor(.8*q),s=c(r),s<a&&(m=r,n=s);;){if(q-m<=1)return{line:g,ch:l-a>a-n?m:q};var t=Math.ceil((m+q)/2),v=c(t);v>a?(q=t,l=v):(m=t,n=v)}}function kb(a){var b=ib(a,!0),c=C(Nb);return{x:c.left+b.x,y:c.top+b.y,yBot:c.top+b.yBot}}function lb(){if(null==Cc){Cc="<pre>";for(var a=0;a<49;++a)Cc+="x<br/>";Cc+="x</pre>"}var b=Qb.clientHeight;return b==Bc?Ac:(Bc=b,Ob.innerHTML=Cc,Ac=Ob.firstChild.offsetHeight/50||1,Ob.innerHTML="",Ac)}function mb(){return Ib.clientWidth==Fc?Dc:(Fc=Ib.clientWidth,Dc=gb("x"))}function nb(){return Nb.offsetTop}function ob(){return Nb.offsetLeft}function pb(a,b){var c,d,e=C(Ib,!0);try{c=a.clientX,d=a.clientY}catch(a){return null}if(!b&&(c-e.left>Ib.clientWidth||d-e.top>Ib.clientHeight))return null;var f=C(Nb,!0);return jb(c-f.left,d-f.top)}function qb(a){function b(){var a=X(Hb.value).join("\n");a!=e&&Ab(ma)(a,"end"),Gb.style.position="relative",Hb.style.cssText=d,gc=!1,ta(!0),qa()}var c=pb(a);if(c&&!window.opera){(E(lc.from,lc.to)||F(c,lc.from)||!F(c,lc.to))&&Ab(Ia)(c.line,c.ch);var d=Hb.style.cssText;Gb.style.position="absolute",Hb.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: white; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",gc=!0;var e=Hb.value=pa();if(ua(),Hb.select(),S){v(a);var f=y(window,"mouseup",function(){f(),setTimeout(b,20)},!0)}else setTimeout(b,50)}}function rb(){clearInterval(Sb);var a=!0;Pb.style.visibility="",Sb=setInterval(function(){Pb.style.visibility=(a=!a)?"":"hidden"},650)}function sb(a){function b(a,b,c){if(a.text)for(var d,e=a.styles,f=g?0:a.text.length-1,i=g?0:e.length-2,j=g?e.length:-2;i!=j;i+=2*h){var k=e[i];if(null==e[i+1]||e[i+1]==m){for(var l=g?0:k.length-1,p=g?k.length:-1;l!=p;l+=h,f+=h)if(f>=b&&f<c&&o.test(d=k.charAt(l))){var q=Gc[d];if(">"==q.charAt(1)==g)n.push(d);else{if(n.pop()!=q.charAt(0))return{pos:f,match:!1};if(!n.length)return{pos:f,match:!0}}}}else f+=h*k.length}}var c=lc.inverted?lc.from:lc.to,d=u(c.line),e=c.ch-1,f=e>=0&&Gc[d.text.charAt(e)]||Gc[d.text.charAt(++e)];if(f){for(var g=(f.charAt(0),">"==f.charAt(1)),h=g?1:-1,i=d.styles,j=e+1,k=0,l=i.length;k<l;k+=2)if((j-=i[k].length)<=0){var m=i[k+1];break}for(var n=[d.text.charAt(e)],o=/[(){}[\]]/,k=c.line,l=g?Math.min(k+100,Yb.size):Math.max(-1,k-100);k!=l;k+=h){var d=u(k),p=k==c.line,q=b(d,p&&g?e+1:0,p&&!g?e:d.text.length);if(q)break}q||(q={pos:null,match:!1});var m=q.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket",r=$a({line:c.line,ch:e},{line:c.line,ch:e+1},m),s=null!=q.pos&&$a({line:k,ch:q.pos},{line:k,ch:q.pos+1},m),t=Ab(function(){r.clear(),s&&s.clear()});a?setTimeout(t,800):jc=t}}function tb(a){for(var b,c,d=a,e=a-40;d>e;--d){if(0==d)return 0;var f=u(d-1);if(f.stateAfter)return d;var g=f.indentation(Bb.tabSize);(null==c||b>g)&&(c=d-1,b=g)}return c}function ub(a){var b=tb(a),c=b&&u(b-1).stateAfter;return c=c?d(Tb,c):e(Tb),Yb.iter(b,a,function(a){a.highlight(Tb,c,Bb.tabSize),a.stateAfter=d(Tb,c)}),b<a&&dc.push({from:b,to:a}),a<Yb.size&&!u(a).stateAfter&&Ub.push(a),c}function vb(a,b){var c=ub(a);Yb.iter(a,b,function(a){a.highlight(Tb,c,Bb.tabSize),a.stateAfter=d(Tb,c)})}function wb(){for(var a=+new Date+Bb.workTime,b=Ub.length;Ub.length;){if(u(oc).stateAfter)var c=Ub.pop();else var c=oc;if(!(c>=Yb.size)){var f=tb(c),g=f&&u(f-1).stateAfter;g=g?d(Tb,g):e(Tb);var h=0,i=Tb.compareStates,j=!1,k=f,l=!1;if(Yb.iter(k,Yb.size,function(b){var e=b.stateAfter;if(+new Date>a)return Ub.push(k),xb(Bb.workDelay),j&&dc.push({from:c,to:k+1}),l=!0;var f=b.highlight(Tb,g,Bb.tabSize);if(f&&(j=!0),b.stateAfter=d(Tb,g),i){if(e&&i(e,g))return!0}else if(f===!1&&e){if(++h>3&&(!Tb.indent||Tb.indent(e,"")==Tb.indent(g,"")))return!0}else h=0;++k}),l)return;j&&dc.push({from:c,to:k+1})}}b&&Bb.onHighlightComplete&&Bb.onHighlightComplete(vc)}function xb(a){Ub.length&&Xb.set(a,Ab(wb))}function yb(){bc=cc=ec=null,dc=[],fc=!1,ic=[]}function zb(){var a,b=!1;fc&&(b=!wa()),dc.length?a=za(dc,!0):(fc&&Da(),hc&&Ca()),b&&wa(),fc&&(va(),rb()),Vb&&!gc&&(bc===!0||bc!==!1&&fc)&&ta(cc),fc&&Bb.matchBrackets&&setTimeout(Ab(function(){jc&&(jc(),jc=null),E(lc.from,lc.to)&&sb(!1)}),20);var c=ec,d=ic;fc&&Bb.onCursorActivity&&Bb.onCursorActivity(vc),c&&Bb.onChange&&vc&&Bb.onChange(vc,c);for(var e=0;e<d.length;++e)d[e](vc);a&&Bb.onUpdate&&Bb.onUpdate(vc)}function Ab(a){return function(){Hc++||yb();try{var b=a.apply(this,arguments)}finally{--Hc||zb()}return b}}var Bb={},Cb=a.defaults;for(var Db in Cb)Cb.hasOwnProperty(Db)&&(Bb[Db]=(j&&j.hasOwnProperty(Db)?j:Cb)[Db]);var Eb=Bb.document,Fb=Eb.createElement("div");Fb.className="CodeMirror"+(Bb.lineWrapping?" CodeMirror-wrap":""),Fb.innerHTML='<div style="overflow: hidden; position: relative; width: 3px; height: 0px;"><textarea style="position: absolute; padding: 0; width: 1px;" wrap="off" autocorrect="off" autocapitalize="off"></textarea></div><div class="CodeMirror-scroll" tabindex="-1"><div style="position: relative"><div style="position: relative"><div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div><div class="CodeMirror-lines"><div style="position: relative"><div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden"></div><pre class="CodeMirror-cursor"> </pre><div></div></div></div></div></div></div>',f.appendChild?f.appendChild(Fb):f(Fb);var Gb=Fb.firstChild,Hb=Gb.firstChild,Ib=Fb.lastChild,Jb=Ib.firstChild,Kb=Jb.firstChild,Lb=Kb.firstChild,Mb=Lb.firstChild,Nb=Lb.nextSibling.firstChild,Ob=Nb.firstChild,Pb=Ob.nextSibling,Qb=Pb.nextSibling;Ya(),/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent)&&(Hb.style.width="0px"),U||(Nb.draggable=!0),null!=Bb.tabindex&&(Hb.tabIndex=Bb.tabindex),Bb.gutter||Bb.lineNumbers||(Lb.style.display="none");try{gb("x")}catch(Rb){throw Rb.message.match(/runtime/i)&&(Rb=new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)")),Rb}var Sb,Tb,Ub,Vb,Wb=new z,Xb=new z,Yb=new l([new k([new i("")])]);Ta();var Zb,$b,_b,ac,bc,cc,dc,ec,fc,gc,hc,ic,jc,kc,lc={from:{line:0,ch:0},to:{line:0,ch:0},inverted:!1},mc=!1,nc=0,oc=0,pc=0,qc=0,rc="",sc=Wa();Ab(function(){B(Bb.value||""),bc=!1})();var tc=new q;y(Ib,"mousedown",Ab(N)),y(Ib,"dblclick",Ab(V)),y(Nb,"dragstart",_),y(Nb,"selectstart",t),S||y(Ib,"contextmenu",qb),y(Ib,"scroll",function(){za([]),Bb.fixedGutter&&(Lb.style.left=Ib.scrollLeft+"px"),Bb.onScroll&&Bb.onScroll(vc)}),y(window,"resize",function(){za(!0)}),y(Hb,"keyup",Ab(da)),y(Hb,"input",ra),y(Hb,"keydown",Ab(ba)),y(Hb,"keypress",Ab(ca)),y(Hb,"focus",ea),y(Hb,"blur",fa),y(Ib,"dragenter",v),y(Ib,"dragover",v),y(Ib,"drop",Ab($)),y(Ib,"paste",function(){ua(),ra()}),y(Hb,"paste",ra),y(Hb,"cut",Ab(function(){ma("")}));var uc;try{uc=Eb.activeElement==Hb}catch(Rb){}uc?setTimeout(ea,20):fa();var vc=Fb.CodeMirror={getValue:M,setValue:Ab(B),getSelection:pa,replaceSelection:Ab(ma),focus:function(){ua(),ea(),ra()},setOption:function(a,b){var c=Bb[a];Bb[a]=b,"mode"==a||"indentUnit"==a?Ta():"readOnly"==a&&b?(fa(),Hb.blur()):"theme"==a?Ya():"lineWrapping"==a&&c!=b?Ab(Va)():"tabSize"==a&&Ab(Xa)(),"lineNumbers"!=a&&"gutter"!=a&&"firstLineNumber"!=a&&"theme"!=a||Ab(Ua)()},getOption:function(a){return Bb[a]},undo:Ab(ia),redo:Ab(ja),indentLine:Ab(function(a,b){r(a)&&Sa(a,null==b?"smart":b?"add":"subtract")}),indentSelection:Ab(Ra),historySize:function(){return{undo:tc.done.length,redo:tc.undone.length}},clearHistory:function(){tc=new q},matchBrackets:Ab(function(){sb(!0)}),getTokenAt:Ab(function(a){return a=Ka(a),u(a.line).getTokenAt(Tb,ub(a.line),a.ch)}),getStateAfter:function(a){return a=Ja(null==a?Yb.size-1:a),ub(a+1)},cursorCoords:function(a){return null==a&&(a=lc.inverted),kb(a?lc.from:lc.to)},charCoords:function(a){return kb(Ka(a))},coordsChar:function(a){var b=C(Nb);return jb(a.x-b.left,a.y-b.top)},markText:Ab($a),setBookmark:_a,setMarker:Ab(ab),clearMarker:Ab(bb),setLineClass:Ab(db),hideLine:Ab(function(a){return eb(a,!0)}),showLine:Ab(function(a){return eb(a,!1)}),onDeleteLine:function(a,b){if("number"==typeof a){if(!r(a))return null;a=u(a)}return(a.handlers||(a.handlers=[])).push(b),a},lineInfo:fb,addWidget:function(a,b,c,d,e){a=ib(Ka(a));var f=a.yBot,g=a.x;if(b.style.position="absolute",Jb.appendChild(b),"over"==d)f=a.y;else if("near"==d){var h=Math.max(Ib.offsetHeight,Yb.height*lb()),i=Math.max(Jb.clientWidth,Nb.clientWidth)-ob();a.yBot+b.offsetHeight>h&&a.y>b.offsetHeight&&(f=a.y-b.offsetHeight),g+b.offsetWidth>i&&(g=i-b.offsetWidth)}b.style.top=f+nb()+"px",b.style.left=b.style.right="","right"==e?(g=Jb.clientWidth-b.offsetWidth,b.style.right="0px"):("left"==e?g=0:"middle"==e&&(g=(Jb.clientWidth-b.offsetWidth)/2),b.style.left=g+ob()+"px"),c&&xa(g,f,g+b.offsetWidth,f+b.offsetHeight)},lineCount:function(){return Yb.size},clipPos:Ka,getCursor:function(a){return null==a&&(a=lc.inverted),G(a?lc.from:lc.to)},somethingSelected:function(){return!E(lc.from,lc.to)},setCursor:Ab(function(a,b,c){null==b&&"number"==typeof a.line?Ia(a.line,a.ch,c):Ia(a,b,c)}),setSelection:Ab(function(a,b,c){(c?Fa:Ga)(Ka(a),Ka(b||a))}),getLine:function(a){if(r(a))return u(a).text},getLineHandle:function(a){if(r(a))return u(a)},setLine:Ab(function(a,b){r(a)&&la(b,{line:a,ch:0},{line:a,ch:u(a).text.length})}),removeLine:Ab(function(a){r(a)&&la("",{line:a,ch:0},Ka({line:a+1,ch:0}))}),replaceRange:Ab(la),getRange:function(a,b){return oa(Ka(a),Ka(b))},execCommand:function(a){return P[a](vc)},moveH:Ab(Ma),deleteH:Ab(Na),moveV:Ab(Oa),toggleOverwrite:function(){mc=!mc},posFromIndex:function(a){var b,c=0;return Yb.iter(0,Yb.size,function(d){var e=d.text.length+1;return e>a?(b=a,!0):(a-=e,void++c)}),Ka({line:c,ch:b})},indexFromPos:function(a){if(a.line<0||a.ch<0)return 0;var b=a.ch;return Yb.iter(0,a.line,function(a){b+=a.text.length+1}),b},operation:function(a){return Ab(a)()},refresh:function(){za(!0)},getInputField:function(){return Hb},getWrapperElement:function(){return Fb},getScrollerElement:function(){return Ib},getGutterElement:function(){return Lb}},wc=null,xc=!1,yc="",zc=null;Za.prototype.clear=Ab(function(){for(var a=1/0,b=-(1/0),c=0,d=this.set.length;c<d;++c){var e=this.set[c],f=e.marked;if(f&&e.parent){var g=n(e);a=Math.min(a,g),b=Math.max(b,g);for(var h=0;h<f.length;++h)f[h].set==this.set&&f.splice(h--,1)}}a!=1/0&&dc.push({from:a,to:b+1})}),Za.prototype.find=function(){for(var a,b,c=0,d=this.set.length;c<d;++c)for(var e=this.set[c],f=e.marked,g=0;g<f.length;++g){var h=f[g];if(h.set==this.set&&(null!=h.from||null!=h.to)){var i=n(e);null!=i&&(null!=h.from&&(a={line:i,ch:h.from}),null!=h.to&&(b={line:i,ch:h.to}))}}return{from:a,to:b}};var Ac,Bc,Cc,Dc,Ec=Math.floor(16777215*Math.random()).toString(16),Fc=0,Gc={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},Hc=0;for(var Ic in O)O.propertyIsEnumerable(Ic)&&!vc.propertyIsEnumerable(Ic)&&(vc[Ic]=O[Ic]);return vc}function b(a,b,c){function d(a,b,c){var e=b[a];if(null!=e)return e;if(null==c&&(c=b.fallthrough),null==c)return b.catchall;if("string"==typeof c)return d(a,Q[c]);for(var f=0,g=c.length;f<g;++f)if(e=d(a,Q[c[f]]),null!=e)return e;return null}return b?d(a,b,c):d(a,Q[c])}function c(a){var b=Z[a.keyCode];return"Ctrl"==b||"Alt"==b||"Shift"==b||"Mod"==b}function d(a,b){if(b===!0)return b;if(a.copyState)return a.copyState(b);var c={};for(var d in b){var e=b[d];e instanceof Array&&(e=e.concat([])),c[d]=e}return c}function e(a,b,c){return!a.startState||a.startState(b,c)}function f(a,b){this.pos=this.start=0,this.string=a,this.tabSize=b||8}function g(a,b,c,d){this.from=a,this.to=b,this.style=c,this.set=d}function h(a){this.from=a,this.to=a,this.line=null}function i(a,b){this.styles=b||[a,null],this.text=a,this.height=1,this.marked=this.gutterMarker=this.className=this.handlers=null,this.stateAfter=this.parent=this.hidden=null}function j(a,b,c,d){for(var e=0,f=0,g=0;f<b;e+=2){var h=c[e],i=f+h.length;0==g?(i>a&&d.push(h.slice(a-f,Math.min(h.length,b-f)),c[e+1]),i>=a&&(g=1)):1==g&&(i>b?d.push(h.slice(0,b-f),c[e+1]):d.push(h,c[e+1])),f=i}}function k(a){this.lines=a,this.parent=null;for(var b=0,c=a.length,d=0;b<c;++b)a[b].parent=this,d+=a[b].height;this.height=d}function l(a){this.children=a;for(var b=0,c=0,d=0,e=a.length;d<e;++d){var f=a[d];b+=f.chunkSize(),c+=f.height,f.parent=this}this.size=b,this.height=c,this.parent=null}function m(a,b){for(;!a.lines;)for(var c=0;;++c){var d=a.children[c],e=d.chunkSize();if(b<e){a=d;break}b-=e}return a.lines[b]}function n(a){if(null==a.parent)return null;for(var b=a.parent,c=J(b.lines,a),d=b.parent;d;b=d,d=d.parent){var e=0;for(d.children.length;d.children[e]!=b;++e)c+=d.children[e].chunkSize()}return c}function o(a,b){var c=0;a:do{for(var d=0,e=a.children.length;d<e;++d){var f=a.children[d],g=f.height;if(b<g){a=f;continue a}b-=g,c+=f.chunkSize()}return c}while(!a.lines);for(var d=0,e=a.lines.length;d<e;++d){var h=a.lines[d],i=h.height;if(b<i)break;b-=i}return c+d}function p(a,b){var c=0;a:do{for(var d=0,e=a.children.length;d<e;++d){var f=a.children[d],g=f.chunkSize();if(b<g){a=f;continue a}b-=g,c+=f.height}return c}while(!a.lines);for(var d=0;d<b;++d)c+=a.lines[d].height;return c}function q(){this.time=0,this.done=[],this.undone=[]}function r(){v(this)}function s(a){return a.stop||(a.stop=r),a}function t(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function u(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function v(a){t(a),u(a)}function w(a){return a.target||a.srcElement}function x(a){return a.which?a.which:1&a.button?1:2&a.button?3:4&a.button?2:void 0}function y(a,b,c,d){
         | 
| 3 | 
            +
            if("function"==typeof a.addEventListener){if(a.addEventListener(b,c,!1),d)return function(){a.removeEventListener(b,c,!1)}}else{var e=function(a){c(a||window.event)};if(a.attachEvent("on"+b,e),d)return function(){a.detachEvent("on"+b,e)}}}function z(){this.id=null}function A(a,b,c){null==b&&(b=a.search(/[^\s\u00a0]/),b==-1&&(b=a.length));for(var d=0,e=0;d<b;++d)"\t"==a.charAt(d)?e+=c-e%c:++e;return e}function B(a){return a.currentStyle?a.currentStyle:window.getComputedStyle(a,null)}function C(a,b){for(var c=a.ownerDocument.body,d=0,e=0,f=!1,g=a;g;g=g.offsetParent){var h=g.offsetLeft,i=g.offsetTop;g==c?(d+=Math.abs(h),e+=Math.abs(i)):(d+=h,e+=i),b&&"fixed"==B(g).position&&(f=!0)}for(var j=b&&!f?null:c,g=a.parentNode;g!=j;g=g.parentNode)null!=g.scrollLeft&&(d-=g.scrollLeft,e-=g.scrollTop);return{left:d,top:e}}function D(a){return a.textContent||a.innerText||a.nodeValue||""}function E(a,b){return a.line==b.line&&a.ch==b.ch}function F(a,b){return a.line<b.line||a.line==b.line&&a.ch<b.ch}function G(a){return{line:a.line,ch:a.ch}}function H(a){return W.textContent=a,W.innerHTML}function I(a,b){if(!b)return a?a.length:0;if(!a)return b.length;for(var c=a.length,d=b.length;c>=0&&d>=0&&a.charAt(c)==b.charAt(d);--c,--d);return d+1}function J(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;c<d;++c)if(a[c]==b)return c;return-1}function K(a){return/\w/.test(a)||a.toUpperCase()!=a.toLowerCase()}a.defaults={value:"",mode:null,theme:"default",indentUnit:2,indentWithTabs:!1,tabSize:4,keyMap:"default",extraKeys:null,electricChars:!0,onKeyEvent:null,lineWrapping:!1,lineNumbers:!1,gutter:!1,fixedGutter:!1,firstLineNumber:1,readOnly:!1,onChange:null,onCursorActivity:null,onGutterClick:null,onHighlightComplete:null,onUpdate:null,onFocus:null,onBlur:null,onScroll:null,matchBrackets:!1,workTime:100,workDelay:200,pollInterval:100,undoDepth:40,tabindex:null,document:window.document};var L=/Mac/.test(navigator.platform),M=(/Win/.test(navigator.platform),{}),N={};a.defineMode=function(b,c){a.defaults.mode||"null"==b||(a.defaults.mode=b),M[b]=c},a.defineMIME=function(a,b){N[a]=b},a.getMode=function(b,c){if("string"==typeof c&&N.hasOwnProperty(c)&&(c=N[c]),"string"==typeof c)var d=c,e={};else if(null!=c)var d=c.name,e=c;var f=M[d];return f?f(b,e||{}):(window.console&&console.warn("No mode "+d+" found, falling back to plain text."),a.getMode(b,"text/plain"))},a.listModes=function(){var a=[];for(var b in M)M.propertyIsEnumerable(b)&&a.push(b);return a},a.listMIMEs=function(){var a=[];for(var b in N)N.propertyIsEnumerable(b)&&a.push({mime:b,mode:N[b]});return a};var O=a.extensions={};a.defineExtension=function(a,b){O[a]=b};var P=a.commands={selectAll:function(a){a.setSelection({line:0,ch:0},{line:a.lineCount()-1})},killLine:function(a){var b=a.getCursor(!0),c=a.getCursor(!1),d=!E(b,c);d||a.getLine(b.line).length!=b.ch?a.replaceRange("",b,d?c:{line:b.line}):a.replaceRange("",b,{line:b.line+1,ch:0})},deleteLine:function(a){var b=a.getCursor().line;a.replaceRange("",{line:b,ch:0},{line:b})},undo:function(a){a.undo()},redo:function(a){a.redo()},goDocStart:function(a){a.setCursor(0,0,!0)},goDocEnd:function(a){a.setSelection({line:a.lineCount()-1},null,!0)},goLineStart:function(a){a.setCursor(a.getCursor().line,0,!0)},goLineStartSmart:function(a){var b=a.getCursor(),c=a.getLine(b.line),d=Math.max(0,c.search(/\S/));a.setCursor(b.line,b.ch<=d&&b.ch?0:d,!0)},goLineEnd:function(a){a.setSelection({line:a.getCursor().line},null,!0)},goLineUp:function(a){a.moveV(-1,"line")},goLineDown:function(a){a.moveV(1,"line")},goPageUp:function(a){a.moveV(-1,"page")},goPageDown:function(a){a.moveV(1,"page")},goCharLeft:function(a){a.moveH(-1,"char")},goCharRight:function(a){a.moveH(1,"char")},goColumnLeft:function(a){a.moveH(-1,"column")},goColumnRight:function(a){a.moveH(1,"column")},goWordLeft:function(a){a.moveH(-1,"word")},goWordRight:function(a){a.moveH(1,"word")},delCharLeft:function(a){a.deleteH(-1,"char")},delCharRight:function(a){a.deleteH(1,"char")},delWordLeft:function(a){a.deleteH(-1,"word")},delWordRight:function(a){a.deleteH(1,"word")},indentAuto:function(a){a.indentSelection("smart")},indentMore:function(a){a.indentSelection("add")},indentLess:function(a){a.indentSelection("subtract")},insertTab:function(a){a.replaceSelection("\t","end")},transposeChars:function(a){var b=a.getCursor(),c=a.getLine(b.line);b.ch>0&&b.ch<c.length-1&&a.replaceRange(c.charAt(b.ch)+c.charAt(b.ch-1),{line:b.line,ch:b.ch-1},{line:b.line,ch:b.ch+1})},newlineAndIndent:function(a){a.replaceSelection("\n","end"),a.indentLine(a.getCursor().line)},toggleOverwrite:function(a){a.toggleOverwrite()}},Q=a.keyMap={};Q.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharRight",Backspace:"delCharLeft",Tab:"indentMore","Shift-Tab":"indentLess",Enter:"newlineAndIndent",Insert:"toggleOverwrite"},Q.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Alt-Up":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Down":"goDocEnd","Ctrl-Left":"goWordLeft","Ctrl-Right":"goWordRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delWordLeft","Ctrl-Delete":"delWordRight","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll",fallthrough:"basic"},Q.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goWordLeft","Alt-Right":"goWordRight","Cmd-Left":"goLineStart","Cmd-Right":"goLineEnd","Alt-Backspace":"delWordLeft","Ctrl-Alt-Backspace":"delWordRight","Alt-Delete":"delWordRight","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll",fallthrough:["basic","emacsy"]},Q["default"]=L?Q.macDefault:Q.pcDefault,Q.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageUp","Shift-Ctrl-V":"goPageDown","Ctrl-D":"delCharRight","Ctrl-H":"delCharLeft","Alt-D":"delWordRight","Alt-Backspace":"delWordLeft","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},a.fromTextArea=function(b,c){function d(){b.value=h.getValue()}function e(){d(),b.form.submit=g,b.form.submit(),b.form.submit=e}if(c||(c={}),c.value=b.value,!c.tabindex&&b.tabindex&&(c.tabindex=b.tabindex),b.form){var f=y(b.form,"submit",d,!0);if("function"==typeof b.form.submit){var g=b.form.submit;b.form.submit=e}}b.style.display="none";var h=a(function(a){b.parentNode.insertBefore(a,b.nextSibling)},c);return h.save=d,h.getTextArea=function(){return b},h.toTextArea=function(){d(),b.parentNode.removeChild(h.getWrapperElement()),b.style.display="",b.form&&(f(),"function"==typeof b.form.submit&&(b.form.submit=g))},h},a.copyState=d,a.startState=e,f.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return 0==this.pos},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.pos<this.string.length)return this.string.charAt(this.pos++)},eat:function(a){var b=this.string.charAt(this.pos);if("string"==typeof a)var c=b==a;else var c=b&&(a.test?a.test(b):a(b));if(c)return++this.pos,b},eatWhile:function(a){for(var b=this.pos;this.eat(a););return this.pos>b},eatSpace:function(){for(var a=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);if(b>-1)return this.pos=b,!0},backUp:function(a){this.pos-=a},column:function(){return A(this.string,this.start,this.tabSize)},indentation:function(){return A(this.string,null,this.tabSize)},match:function(a,b,c){function d(a){return c?a.toLowerCase():a}if("string"!=typeof a){var e=this.string.slice(this.pos).match(a);return e&&b!==!1&&(this.pos+=e[0].length),e}if(d(this.string).indexOf(d(a),this.pos)==this.pos)return b!==!1&&(this.pos+=a.length),!0},current:function(){return this.string.slice(this.start,this.pos)}},a.StringStream=f,g.prototype={attach:function(a){this.set.push(a)},detach:function(a){var b=J(this.set,a);b>-1&&this.set.splice(b,1)},split:function(a,b){if(this.to<=a&&null!=this.to)return null;var c=this.from<a||null==this.from?null:this.from-a+b,d=null==this.to?null:this.to-a+b;return new g(c,d,this.style,this.set)},dup:function(){return new g(null,null,this.style,this.set)},clipTo:function(a,b,c,d,e){null!=this.from&&this.from>=b&&(this.from=Math.max(d,this.from)+e),null!=this.to&&this.to>b&&(this.to=d<this.to?this.to+e:b),a&&d>this.from&&(d<this.to||null==this.to)&&(this.from=null),c&&(b<this.to||null==this.to)&&(b>this.from||null==this.from)&&(this.to=null)},isDead:function(){return null!=this.from&&null!=this.to&&this.from>=this.to},sameSet:function(a){return this.set==a.set}},h.prototype={attach:function(a){this.line=a},detach:function(a){this.line==a&&(this.line=null)},split:function(a,b){if(a<this.from)return this.from=this.to=this.from-a+b,this},isDead:function(){return this.from>this.to},clipTo:function(a,b,c,d,e){(a||b<this.from)&&(c||d>this.to)?(this.from=0,this.to=-1):this.from>b&&(this.from=this.to=Math.max(d,this.from)+e)},sameSet:function(a){return!1},find:function(){return this.line&&this.line.parent?{line:n(this.line),ch:this.from}:null},clear:function(){if(this.line){var a=J(this.line.marked,this);a!=-1&&this.line.marked.splice(a,1),this.line=null}}},i.inheritMarks=function(a,b){var c=new i(a),d=b&&b.marked;if(d)for(var e=0;e<d.length;++e)if(null==d[e].to&&d[e].style){var f=c.marked||(c.marked=[]),g=d[e],h=g.dup();f.push(h),h.attach(c)}return c},i.prototype={replace:function(a,b,c){var d=[],e=this.marked,f=null==b?this.text.length:b;if(j(0,a,this.styles,d),c&&d.push(c,null),j(f,this.text.length,this.styles,d),this.styles=d,this.text=this.text.slice(0,a)+c+this.text.slice(f),this.stateAfter=null,e)for(var g=c.length-(f-a),h=0,i=e[h];h<e.length;++h)i.clipTo(null==a,a||0,null==b,f,g),i.isDead()&&(i.detach(this),e.splice(h--,1))},split:function(a,b){var c=[b,null],d=this.marked;j(a,this.text.length,this.styles,c);var e=new i(b+this.text.slice(a),c);if(d)for(var f=0;f<d.length;++f){var g=d[f],h=g.split(a,b.length);h&&(e.marked||(e.marked=[]),e.marked.push(h),h.attach(e))}return e},append:function(a){var b=this.text.length,c=a.marked,d=this.marked;if(this.text+=a.text,j(0,a.text.length,a.styles,this.styles),d)for(var e=0;e<d.length;++e)null==d[e].to&&(d[e].to=b);if(c&&c.length){d||(this.marked=d=[]);a:for(var e=0;e<c.length;++e){var f=c[e];if(!f.from)for(var g=0;g<d.length;++g){var h=d[g];if(h.to==b&&h.sameSet(f)){h.to=null==f.to?null:f.to+b,h.isDead()&&(h.detach(this),c.splice(e--,1));continue a}}d.push(f),f.attach(this),f.from+=b,null!=f.to&&(f.to+=b)}}},fixMarkEnds:function(a){var b=this.marked,c=a.marked;if(b)for(var d=0;d<b.length;++d){var e=b[d],f=null==e.to;if(f&&c)for(var g=0;g<c.length;++g)if(c[g].sameSet(e)){f=!1;break}f&&(e.to=this.text.length)}},fixMarkStarts:function(){var a=this.marked;if(a)for(var b=0;b<a.length;++b)null==a[b].from&&(a[b].from=0)},addMark:function(a){a.attach(this),null==this.marked&&(this.marked=[]),this.marked.push(a),this.marked.sort(function(a,b){return(a.from||0)-(b.from||0)})},highlight:function(a,b,c){var d,e=new f(this.text,c),g=this.styles,h=0,i=!1,j=g[0];for(""==this.text&&a.blankLine&&a.blankLine(b);!e.eol();){var k=a.token(e,b),l=this.text.slice(e.start,e.pos);if(e.start=e.pos,h&&g[h-1]==k?g[h-2]+=l:l&&(!i&&(g[h+1]!=k||h&&g[h-2]!=d)&&(i=!0),g[h++]=l,g[h++]=k,d=j,j=g[h]),e.pos>5e3){g[h++]=this.text.slice(e.pos),g[h++]=null;break}}return g.length!=h&&(g.length=h,i=!0),h&&g[h-2]!=d&&(i=!0),i||g.length<5&&this.text.length<10&&null},getTokenAt:function(a,b,c){for(var d=this.text,e=new f(d);e.pos<c&&!e.eol();){e.start=e.pos;var g=a.token(e,b)}return{start:e.start,end:e.pos,string:e.current(),className:g||null,state:b}},indentation:function(a){return A(this.text,null,a)},getHTML:function(a,b,c,d,e){function f(a,b){a&&(i&&T&&" "==a.charAt(0)&&(a=" "+a.slice(1)),i=!1,b?h.push('<span class="',b,'">',H(a).replace(/\t/g,d),"</span>"):h.push(H(a).replace(/\t/g,d)))}function g(){l&&(r+=1,s=r<l.length?l[r]:null)}var h=[],i=!0;c&&h.push(this.className?'<pre class="'+this.className+'">':"<pre>");var j=this.styles,k=this.text,l=this.marked;a==b&&(a=null);var m=k.length;if(null!=e&&(m=Math.min(e,m)),k||null!=e)if(l||null!=a){var n,o=0,p=0,q="",r=-1,s=null;for(g();o<m;){var t=m,u="";for(null!=a&&(a>o?t=a:(null==b||b>o)&&(u=" CodeMirror-selected",null!=b&&(t=Math.min(t,b))));s&&null!=s.to&&s.to<=o;)g();for(s&&(s.from>o?t=Math.min(t,s.from):(u+=" "+s.style,null!=s.to&&(t=Math.min(t,s.to))));;){var v=o+q.length,w=n;if(u&&(w=n?n+u:u),f(v>t?q.slice(0,t-o):q,w),v>=t){q=q.slice(t-o),o=t;break}o=v,q=j[p++],n="cm-"+j[p++]}}null!=a&&null==b&&f(" ","CodeMirror-selected")}else for(var p=0,x=0;x<m;p+=2){var y=j[p],n=j[p+1],z=y.length;x+z>m&&(y=y.slice(0,m-x)),x+=z,f(y,n&&"cm-"+n)}else f(" ",null!=a&&null==b?"CodeMirror-selected":null);return c&&h.push("</pre>"),h.join("")},cleanUp:function(){if(this.parent=null,this.marked)for(var a=0,b=this.marked.length;a<b;++a)this.marked[a].detach(this)}},k.prototype={chunkSize:function(){return this.lines.length},remove:function(a,b,c){for(var d=a,e=a+b;d<e;++d){var f=this.lines[d];if(this.height-=f.height,f.cleanUp(),f.handlers)for(var g=0;g<f.handlers.length;++g)c.push(f.handlers[g])}this.lines.splice(a,b)},collapse:function(a){a.splice.apply(a,[a.length,0].concat(this.lines))},insertHeight:function(a,b,c){this.height+=c,this.lines.splice.apply(this.lines,[a,0].concat(b));for(var d=0,e=b.length;d<e;++d)b[d].parent=this},iterN:function(a,b,c){for(var d=a+b;a<d;++a)if(c(this.lines[a]))return!0}},l.prototype={chunkSize:function(){return this.size},remove:function(a,b,c){this.size-=b;for(var d=0;d<this.children.length;++d){var e=this.children[d],f=e.chunkSize();if(a<f){var g=Math.min(b,f-a),h=e.height;if(e.remove(a,g,c),this.height-=h-e.height,f==g&&(this.children.splice(d--,1),e.parent=null),0==(b-=g))break;a=0}else a-=f}if(this.size-b<25){var i=[];this.collapse(i),this.children=[new k(i)]}},collapse:function(a){for(var b=0,c=this.children.length;b<c;++b)this.children[b].collapse(a)},insert:function(a,b){for(var c=0,d=0,e=b.length;d<e;++d)c+=b[d].height;this.insertHeight(a,b,c)},insertHeight:function(a,b,c){this.size+=b.length,this.height+=c;for(var d=0,e=this.children.length;d<e;++d){var f=this.children[d],g=f.chunkSize();if(a<=g){if(f.insertHeight(a,b,c),f.lines&&f.lines.length>50){for(;f.lines.length>50;){var h=f.lines.splice(f.lines.length-25,25),i=new k(h);f.height-=i.height,this.children.splice(d+1,0,i),i.parent=this}this.maybeSpill()}break}a-=g}},maybeSpill:function(){if(!(this.children.length<=10)){var a=this;do{var b=a.children.splice(a.children.length-5,5),c=new l(b);if(a.parent){a.size-=c.size,a.height-=c.height;var d=J(a.parent.children,a);a.parent.children.splice(d+1,0,c)}else{var e=new l(a.children);e.parent=a,a.children=[e,c],a=e}c.parent=a.parent}while(a.children.length>10);a.parent.maybeSpill()}},iter:function(a,b,c){this.iterN(a,b-a,c)},iterN:function(a,b,c){for(var d=0,e=this.children.length;d<e;++d){var f=this.children[d],g=f.chunkSize();if(a<g){var h=Math.min(b,g-a);if(f.iterN(a,h,c))return!0;if(0==(b-=h))break;a=0}else a-=g}}},q.prototype={addChange:function(a,b,c){this.undone.length=0;var d=+new Date,e=this.done[this.done.length-1];if(d-this.time>400||!e||e.start>a+b||e.start+e.added<a-e.added+e.old.length)this.done.push({start:a,added:b,old:c});else{var f=0;if(a<e.start){for(var g=e.start-a-1;g>=0;--g)e.old.unshift(c[g]);e.added+=e.start-a,e.start=a}else e.start<a&&(f=a-e.start,b+=f);for(var g=e.added-f,h=c.length;g<h;++g)e.old.push(c[g]);e.added<b&&(e.added=b)}this.time=d}},a.e_stop=v,a.e_preventDefault=t,a.e_stopPropagation=u,a.connect=y,z.prototype={set:function(a,b){clearTimeout(this.id),this.id=setTimeout(b,a)}};var R=function(){if(/MSIE [1-8]\b/.test(navigator.userAgent))return!1;var a=document.createElement("div");return"draggable"in a}(),S=/gecko\/\d{7}/i.test(navigator.userAgent),T=/MSIE \d/.test(navigator.userAgent),U=/WebKit\//.test(navigator.userAgent),V="\n";!function(){var a=document.createElement("textarea");a.value="foo\nbar",a.value.indexOf("\r")>-1&&(V="\r\n")}(),null!=document.documentElement.getBoundingClientRect&&(C=function(a,b){try{var c=a.getBoundingClientRect();c={top:c.top,left:c.left}}catch(d){c={top:0,left:0}}if(!b)if(null==window.pageYOffset){var e=document.documentElement||document.body.parentNode;null==e.scrollTop&&(e=document.body),c.top+=e.scrollTop,c.left+=e.scrollLeft}else c.top+=window.pageYOffset,c.left+=window.pageXOffset;return c});var W=document.createElement("pre");"\na"==H("a")?H=function(a){return W.textContent=a,W.innerHTML.slice(1)}:"\t"!=H("\t")&&(H=function(a){return W.innerHTML="",W.appendChild(document.createTextNode(a)),W.innerHTML}),a.htmlEscape=H;var X=3!="\n\nb".split(/\n/).length?function(a){for(var b,c=0,d=[];(b=a.indexOf("\n",c))>-1;)d.push(a.slice(c,"\r"==a.charAt(b-1)?b-1:b)),c=b+1;return d.push(a.slice(c)),d}:function(a){return a.split(/\r?\n/)};a.splitLines=X;var Y=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return!(!b||b.parentElement()!=a)&&0!=b.compareEndPoints("StartToEnd",b)};a.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}}),a.defineMIME("text/plain","null");var Z={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",91:"Mod",92:"Mod",93:"Mod",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63276:"PageUp",63277:"PageDown",63275:"End",63273:"Home",63234:"Left",63232:"Up",63235:"Right",63233:"Down",63302:"Insert",63272:"Delete"};return a.keyNames=Z,function(){for(var a=0;a<10;a++)Z[a+48]=String(a);for(var a=65;a<=90;a++)Z[a]=String.fromCharCode(a);for(var a=1;a<=12;a++)Z[a+111]=Z[a+63235]="F"+a}(),a}();CodeMirror.defineMode("xml",function(a,b){function c(a,b){function c(c){return b.tokenize=c,c(a,b)}var e=a.next();if("<"==e){if(a.eat("!"))return a.eat("[")?a.match("CDATA[")?c(f("atom","]]>")):null:a.match("--")?c(f("comment","-->")):a.match("DOCTYPE",!0,!0)?(a.eatWhile(/[\w\._\-]/),c(g(1))):null;if(a.eat("?"))return a.eatWhile(/[\w\._\-]/),b.tokenize=f("meta","?>"),"meta";s=a.eat("/")?"closeTag":"openTag",a.eatSpace(),r="";for(var h;h=a.eat(/[^\s\u00a0=<>\"\'\/?]/);)r+=h;return b.tokenize=d,"tag"}return"&"==e?(a.eatWhile(/[^;]/),a.eat(";"),"atom"):(a.eatWhile(/[^&<]/),null)}function d(a,b){var d=a.next();return">"==d||"/"==d&&a.eat(">")?(b.tokenize=c,s=">"==d?"endTag":"selfcloseTag","tag"):"="==d?(s="equals",null):/[\'\"]/.test(d)?(b.tokenize=e(d),b.tokenize(a,b)):(a.eatWhile(/[^\s\u00a0=<>\"\'\/?]/),"word")}function e(a){return function(b,c){for(;!b.eol();)if(b.next()==a){c.tokenize=d;break}return"string"}}function f(a,b){return function(d,e){for(;!d.eol();){if(d.match(b)){e.tokenize=c;break}d.next()}return a}}function g(a){return function(b,d){for(var e;null!=(e=b.next());){if("<"==e)return d.tokenize=g(a+1),d.tokenize(b,d);if(">"==e){if(1==a){d.tokenize=c;break}return d.tokenize=g(a-1),d.tokenize(b,d)}}return"meta"}}function h(){for(var a=arguments.length-1;a>=0;a--)t.cc.push(arguments[a])}function i(){return h.apply(null,arguments),!0}function j(a,b){var c=w.doNotIndent.hasOwnProperty(a)||t.context&&t.context.noIndent;t.context={prev:t.context,tagName:a,indent:t.indented,startOfLine:b,noIndent:c}}function k(){t.context&&(t.context=t.context.prev)}function l(a){if("openTag"==a)return t.tagName=r,i(o,m(t.startOfLine));if("closeTag"==a){var b=!1;return b=!t.context||t.context.tagName!=r,b&&(u="error"),i(n(b))}return i()}function m(a){return function(b){return"selfcloseTag"==b||"endTag"==b&&w.autoSelfClosers.hasOwnProperty(t.tagName.toLowerCase())?i():"endTag"==b?(j(t.tagName,a),i()):i()}}function n(a){return function(b){return a&&(u="error"),"endTag"==b?(k(),i()):(u="error",i(arguments.callee))}}function o(a){return"word"==a?(u="attribute",i(o)):"equals"==a?i(p,o):"string"==a?(u="error",i(o)):h()}function p(a){return"word"==a&&w.allowUnquoted?(u="string",i()):"string"==a?i(q):h()}function q(a){return"string"==a?i(q):h()}var r,s,t,u,v=a.indentUnit,w=b.htmlMode?{autoSelfClosers:{br:!0,img:!0,hr:!0,link:!0,input:!0,meta:!0,col:!0,frame:!0,base:!0,area:!0},doNotIndent:{pre:!0},allowUnquoted:!0}:{autoSelfClosers:{},doNotIndent:{},allowUnquoted:!1},x=b.alignCDATA;return{startState:function(){return{tokenize:c,cc:[],indented:0,startOfLine:!0,tagName:null,context:null}},token:function(a,b){if(a.sol()&&(b.startOfLine=!0,b.indented=a.indentation()),a.eatSpace())return null;u=s=r=null;var c=b.tokenize(a,b);if(b.type=s,(c||s)&&"comment"!=c)for(t=b;;){var d=b.cc.pop()||l;if(d(s||c))break}return b.startOfLine=!1,u||c},indent:function(a,b,e){var f=a.context;if(a.tokenize!=d&&a.tokenize!=c||f&&f.noIndent)return e?e.match(/^(\s*)/)[0].length:0;if(x&&/<!\[CDATA\[/.test(b))return 0;for(f&&/^<\//.test(b)&&(f=f.prev);f&&!f.startOfLine;)f=f.prev;return f?f.indent+v:0},compareStates:function(a,b){if(a.indented!=b.indented||a.tokenize!=b.tokenize)return!1;for(var c=a.context,d=b.context;;c=c.prev,d=d.prev){if(!c||!d)return c==d;if(c.tagName!=d.tagName)return!1}},electricChars:"/"}}),CodeMirror.defineMIME("application/xml","xml"),CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:!0}),CodeMirror.defineMode("javascript",function(a,b){function c(a,b,c){return b.tokenize=c,c(a,b)}function d(a,b){for(var c,d=!1;null!=(c=a.next());){if(c==b&&!d)return!1;d=!d&&"\\"==c}return d}function e(a,b,c){return K=a,L=c,b}function f(a,b){var f=a.next();if('"'==f||"'"==f)return c(a,b,g(f));if(/[\[\]{}\(\),;\:\.]/.test(f))return e(f);if("0"==f&&a.eat(/x/i))return a.eatWhile(/[\da-f]/i),e("number","number");if(/\d/.test(f))return a.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/),e("number","number");if("/"==f)return a.eat("*")?c(a,b,h):a.eat("/")?(a.skipToEnd(),e("comment","comment")):b.reAllowed?(d(a,"/"),a.eatWhile(/[gimy]/),e("regexp","string")):(a.eatWhile(P),e("operator",null,a.current()));if("#"==f)return a.skipToEnd(),e("error","error");if(P.test(f))return a.eatWhile(P),e("operator",null,a.current());a.eatWhile(/[\w\$_]/);var i=a.current(),j=O.propertyIsEnumerable(i)&&O[i];return j&&b.kwAllowed?e(j.type,j.style,i):e("variable","variable",i)}function g(a){return function(b,c){return d(b,a)||(c.tokenize=f),e("string","string")}}function h(a,b){for(var c,d=!1;c=a.next();){if("/"==c&&d){b.tokenize=f;break}d="*"==c}return e("comment","comment")}function i(a,b,c,d,e,f){this.indented=a,this.column=b,this.type=c,this.prev=e,this.info=f,null!=d&&(this.align=d)}function j(a,b){for(var c=a.localVars;c;c=c.next)if(c.name==b)return!0}function k(a,b,c,d,e){var f=a.cc;for(R.state=a,R.stream=e,R.marked=null,R.cc=f,a.lexical.hasOwnProperty("align")||(a.lexical.align=!0);;){var g=f.length?f.pop():N?u:t;if(g(c,d)){for(;f.length&&f[f.length-1].lex;)f.pop()();return R.marked?R.marked:"variable"==c&&j(a,d)?"variable-2":b}}}function l(){for(var a=arguments.length-1;a>=0;a--)R.cc.push(arguments[a])}function m(){return l.apply(null,arguments),!0}function n(a){var b=R.state;if(b.context){R.marked="def";for(var c=b.localVars;c;c=c.next)if(c.name==a)return;b.localVars={name:a,next:b.localVars}}}function o(){R.state.context||(R.state.localVars=S),R.state.context={prev:R.state.context,vars:R.state.localVars}}function p(){R.state.localVars=R.state.context.vars,R.state.context=R.state.context.prev}function q(a,b){var c=function(){var c=R.state;c.lexical=new i(c.indented,R.stream.column(),a,null,c.lexical,b)};return c.lex=!0,c}function r(){var a=R.state;a.lexical.prev&&(")"==a.lexical.type&&(a.indented=a.lexical.indented),a.lexical=a.lexical.prev)}function s(a){return function(b){return b==a?m():";"==a?l():m(arguments.callee)}}function t(a){return"var"==a?m(q("vardef"),C,s(";"),r):"keyword a"==a?m(q("form"),u,t,r):"keyword b"==a?m(q("form"),t,r):"{"==a?m(q("}"),B,r):";"==a?m():"function"==a?m(I):"for"==a?m(q("form"),s("("),q(")"),E,s(")"),r,t,r):"variable"==a?m(q("stat"),x):"switch"==a?m(q("form"),u,q("}","switch"),s("{"),B,r,r):"case"==a?m(u,s(":")):"default"==a?m(s(":")):"catch"==a?m(q("form"),o,s("("),J,s(")"),t,r,p):l(q("stat"),u,s(";"),r)}function u(a){return Q.hasOwnProperty(a)?m(w):"function"==a?m(I):"keyword c"==a?m(v):"("==a?m(q(")"),u,s(")"),r,w):"operator"==a?m(u):"["==a?m(q("]"),A(u,"]"),r,w):"{"==a?m(q("}"),A(z,"}"),r,w):m()}function v(a){return a.match(/[;\}\)\],]/)?l():l(u)}function w(a,b){if("operator"==a&&/\+\+|--/.test(b))return m(w);if("operator"==a)return m(u);if(";"!=a)return"("==a?m(q(")"),A(u,")"),r,w):"."==a?m(y,w):"["==a?m(q("]"),u,s("]"),r,w):void 0}function x(a){return":"==a?m(r,t):l(w,s(";"),r)}function y(a){if("variable"==a)return R.marked="property",m()}function z(a){if("variable"==a&&(R.marked="property"),Q.hasOwnProperty(a))return m(s(":"),u)}function A(a,b){function c(d){return","==d?m(a,c):d==b?m():m(s(b))}return function(d){return d==b?m():l(a,c)}}function B(a){return"}"==a?m():l(t,B)}function C(a,b){return"variable"==a?(n(b),m(D)):m()}function D(a,b){return"="==b?m(u,D):","==a?m(C):void 0}function E(a){return"var"==a?m(C,G):";"==a?l(G):"variable"==a?m(F):l(G)}function F(a,b){return"in"==b?m(u):m(w,G)}function G(a,b){return";"==a?m(H):"in"==b?m(u):m(u,s(";"),H)}function H(a){")"!=a&&m(u)}function I(a,b){return"variable"==a?(n(b),m(I)):"("==a?m(q(")"),o,A(J,")"),r,t,p):void 0}function J(a,b){if("variable"==a)return n(b),m()}var K,L,M=a.indentUnit,N=b.json,O=function(){function a(a){return{type:a,style:"keyword"}}var b=a("keyword a"),c=a("keyword b"),d=a("keyword c"),e=a("operator"),f={type:"atom",style:"atom"};return{"if":b,"while":b,"with":b,"else":c,"do":c,"try":c,"finally":c,"return":d,"break":d,"continue":d,"new":d,"delete":d,"throw":d,"var":a("var"),"const":a("var"),"let":a("var"),"function":a("function"),"catch":a("catch"),"for":a("for"),"switch":a("switch"),"case":a("case"),"default":a("default"),"in":e,"typeof":e,"instanceof":e,"true":f,"false":f,"null":f,undefined:f,NaN:f,Infinity:f}}(),P=/[+\-*&%=<>!?|]/,Q={atom:!0,number:!0,variable:!0,string:!0,regexp:!0},R={state:null,column:null,marked:null,cc:null},S={name:"this",next:{name:"arguments"}};return r.lex=!0,{startState:function(a){return{tokenize:f,reAllowed:!0,kwAllowed:!0,cc:[],lexical:new i((a||0)-M,0,"block",(!1)),localVars:null,context:null,indented:0}},token:function(a,b){if(a.sol()&&(b.lexical.hasOwnProperty("align")||(b.lexical.align=!1),b.indented=a.indentation()),a.eatSpace())return null;var c=b.tokenize(a,b);return"comment"==K?c:(b.reAllowed="operator"==K||"keyword c"==K||K.match(/^[\[{}\(,;:]$/),b.kwAllowed="."!=K,k(b,c,K,L,a))},indent:function(a,b){if(a.tokenize!=f)return 0;var c=b&&b.charAt(0),d=a.lexical,e=d.type,g=c==e;return"vardef"==e?d.indented+4:"form"==e&&"{"==c?d.indented:"stat"==e||"form"==e?d.indented+M:"switch"!=d.info||g?d.align?d.column+(g?0:1):d.indented+(g?0:M):d.indented+(/^(?:case|default)\b/.test(b)?M:2*M)},electricChars:":{}"}}),CodeMirror.defineMIME("text/javascript","javascript"),CodeMirror.defineMIME("application/json",{name:"javascript",json:!0}),CodeMirror.defineMode("css",function(a){function b(a,b){return g=b,a}function c(a,c){var g=a.next();return"@"==g?(a.eatWhile(/[\w\\\-]/),b("meta",a.current())):"/"==g&&a.eat("*")?(c.tokenize=d,d(a,c)):"<"==g&&a.eat("!")?(c.tokenize=e,e(a,c)):"="!=g?"~"!=g&&"|"!=g||!a.eat("=")?'"'==g||"'"==g?(c.tokenize=f(g),c.tokenize(a,c)):"#"==g?(a.eatWhile(/[\w\\\-]/),b("atom","hash")):"!"==g?(a.match(/^\s*\w*/),b("keyword","important")):/\d/.test(g)?(a.eatWhile(/[\w.%]/),b("number","unit")):/[,.+>*\/]/.test(g)?b(null,"select-op"):/[;{}:\[\]]/.test(g)?b(null,g):(a.eatWhile(/[\w\\\-]/),b("variable","variable")):b(null,"compare"):void b(null,"compare")}function d(a,d){for(var e,f=!1;null!=(e=a.next());){if(f&&"/"==e){d.tokenize=c;break}f="*"==e}return b("comment","comment")}function e(a,d){for(var e,f=0;null!=(e=a.next());){if(f>=2&&">"==e){d.tokenize=c;break}f="-"==e?f+1:0}return b("comment","comment")}function f(a){return function(d,e){for(var f,g=!1;null!=(f=d.next())&&(f!=a||g);)g=!g&&"\\"==f;return g||(e.tokenize=c),b("string","string")}}var g,h=a.indentUnit;return{startState:function(a){return{tokenize:c,baseIndent:a||0,stack:[]}},token:function(a,b){if(a.eatSpace())return null;var c=b.tokenize(a,b),d=b.stack[b.stack.length-1];return"hash"==g&&"rule"==d?c="atom":"variable"==c&&("rule"==d?c="number":d&&"@media{"!=d||(c="tag")),"rule"==d&&/^[\{\};]$/.test(g)&&b.stack.pop(),"{"==g?"@media"==d?b.stack[b.stack.length-1]="@media{":b.stack.push("{"):"}"==g?b.stack.pop():"@media"==g?b.stack.push("@media"):"{"==d&&"comment"!=g&&b.stack.push("rule"),c},indent:function(a,b){var c=a.stack.length;return/^\}/.test(b)&&(c-="rule"==a.stack[a.stack.length-1]?2:1),a.baseIndent+c*h},electricChars:"}"}}),CodeMirror.defineMIME("text/css","css"),CodeMirror.defineMode("htmlmixed",function(a,b){function c(a,b){var c=g.token(a,b.htmlState);return"tag"==c&&">"==a.current()&&b.htmlState.context&&(/^script$/i.test(b.htmlState.context.tagName)?(b.token=e,b.localState=h.startState(g.indent(b.htmlState,"")),b.mode="javascript"):/^style$/i.test(b.htmlState.context.tagName)&&(b.token=f,b.localState=i.startState(g.indent(b.htmlState,"")),b.mode="css")),c}function d(a,b,c){var d=a.current(),e=d.search(b);return e>-1&&a.backUp(d.length-e),c}function e(a,b){return a.match(/^<\/\s*script\s*>/i,!1)?(b.token=c,b.curState=null,b.mode="html",c(a,b)):d(a,/<\/\s*script\s*>/,h.token(a,b.localState))}function f(a,b){return a.match(/^<\/\s*style\s*>/i,!1)?(b.token=c,b.localState=null,b.mode="html",c(a,b)):d(a,/<\/\s*style\s*>/,i.token(a,b.localState))}var g=CodeMirror.getMode(a,{name:"xml",htmlMode:!0}),h=CodeMirror.getMode(a,"javascript"),i=CodeMirror.getMode(a,"css");return{startState:function(){var a=g.startState();return{token:c,localState:null,mode:"html",htmlState:a}},copyState:function(a){if(a.localState)var b=CodeMirror.copyState(a.token==f?i:h,a.localState);return{token:a.token,localState:b,mode:a.mode,htmlState:CodeMirror.copyState(g,a.htmlState)}},token:function(a,b){return b.token(a,b)},indent:function(a,b){return a.token==c||/^\s*<\//.test(b)?g.indent(a.htmlState,b):a.token==e?h.indent(a.localState,b):i.indent(a.localState,b)},compareStates:function(a,b){return g.compareStates(a.htmlState,b.htmlState)},electricChars:"/{}:"}}),CodeMirror.defineMIME("text/html","htmlmixed");
         |