Dotclear

Changeset 3758:6338fb89e8df


Ignore:
Timestamp:
06/13/18 12:31:58 (5 years ago)
Author:
franck <carnet.franck.paul@…>
Branch:
default
Message:

Update Codemirror to 5.38.0

Location:
admin/js/codemirror
Files:
7 added
9 edited

Legend:

Unmodified
Added
Removed
  • admin/js/codemirror/addon/edit/closebrackets.js

    r3617 r3758  
    130130          curType = "skip"; 
    131131      } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && 
    132                  cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && 
    133                  (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { 
     132                 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) { 
     133        if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass; 
    134134        curType = "addFour"; 
    135135      } else if (identical) { 
  • admin/js/codemirror/addon/edit/matchbrackets.js

    r3617 r3758  
    103103  } 
    104104 
    105   var currentlyHighlighted = null; 
    106105  function doMatchBrackets(cm) { 
    107106    cm.operation(function() { 
    108       if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} 
    109       currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); 
     107      if (cm.state.matchBrackets.currentlyHighlighted) { 
     108        cm.state.matchBrackets.currentlyHighlighted(); 
     109        cm.state.matchBrackets.currentlyHighlighted = null; 
     110      } 
     111      cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); 
    110112    }); 
    111113  } 
     
    114116    if (old && old != CodeMirror.Init) { 
    115117      cm.off("cursorActivity", doMatchBrackets); 
    116       if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} 
     118      if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) { 
     119        cm.state.matchBrackets.currentlyHighlighted(); 
     120        cm.state.matchBrackets.currentlyHighlighted = null; 
     121      } 
    117122    } 
    118123    if (val) { 
  • admin/js/codemirror/addon/mode/multiplex.js

    r3251 r3758  
    5151            if (!other.parseDelimiters) stream.match(other.open); 
    5252            state.innerActive = other; 
    53             state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); 
     53 
     54            // Get the outer indent, making sure to handle CodeMirror.Pass 
     55            var outerIndent = 0; 
     56            if (outer.indent) { 
     57              var possibleOuterIndent = outer.indent(state.outer, ""); 
     58              if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent; 
     59            } 
     60 
     61            state.inner = CodeMirror.startState(other.mode, outerIndent); 
    5462            return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open"); 
    5563          } else if (found != -1 && found < cutOff) { 
  • admin/js/codemirror/lib/codemirror.css

    r3617 r3758  
    271271  position: relative; 
    272272  z-index: 2; 
    273   overflow: auto; 
     273  padding: 0.1px; /* Force widget margins to stay inside of the container */ 
    274274} 
    275275 
  • admin/js/codemirror/lib/codemirror.js

    r3542 r3758  
    99 
    1010(function (global, factory) { 
    11      typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 
    12      typeof define === 'function' && define.amd ? define(factory) : 
    13      (global.CodeMirror = factory()); 
     11  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 
     12  typeof define === 'function' && define.amd ? define(factory) : 
     13  (global.CodeMirror = factory()); 
    1414}(this, (function () { 'use strict'; 
    1515 
    1616// Kludges for bugs and behavior differences that can't be feature 
    1717// detected are enabled based on userAgent etc sniffing. 
    18 var userAgent = navigator.userAgent; 
    19 var platform = navigator.platform; 
    20  
    21 var gecko = /gecko\/\d/i.test(userAgent); 
    22 var ie_upto10 = /MSIE \d/.test(userAgent); 
    23 var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); 
    24 var edge = /Edge\/(\d+)/.exec(userAgent); 
    25 var ie = ie_upto10 || ie_11up || edge; 
    26 var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]); 
    27 var webkit = !edge && /WebKit\//.test(userAgent); 
    28 var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); 
    29 var chrome = !edge && /Chrome\//.test(userAgent); 
    30 var presto = /Opera\//.test(userAgent); 
    31 var safari = /Apple Computer/.test(navigator.vendor); 
    32 var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); 
    33 var phantom = /PhantomJS/.test(userAgent); 
    34  
    35 var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); 
    36 var android = /Android/.test(userAgent); 
     18var userAgent = navigator.userAgent 
     19var platform = navigator.platform 
     20 
     21var gecko = /gecko\/\d/i.test(userAgent) 
     22var ie_upto10 = /MSIE \d/.test(userAgent) 
     23var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent) 
     24var edge = /Edge\/(\d+)/.exec(userAgent) 
     25var ie = ie_upto10 || ie_11up || edge 
     26var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]) 
     27var webkit = !edge && /WebKit\//.test(userAgent) 
     28var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent) 
     29var chrome = !edge && /Chrome\//.test(userAgent) 
     30var presto = /Opera\//.test(userAgent) 
     31var safari = /Apple Computer/.test(navigator.vendor) 
     32var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent) 
     33var phantom = /PhantomJS/.test(userAgent) 
     34 
     35var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent) 
     36var android = /Android/.test(userAgent) 
    3737// This is woefully incomplete. Suggestions for alternative methods welcome. 
    38 var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); 
    39 var mac = ios || /Mac/.test(platform); 
    40 var chromeOS = /\bCrOS\b/.test(userAgent); 
    41 var windows = /win/i.test(platform); 
    42  
    43 var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); 
    44 if (presto_version) { presto_version = Number(presto_version[1]); } 
    45 if (presto_version && presto_version >= 15) { presto = false; webkit = true; } 
     38var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent) 
     39var mac = ios || /Mac/.test(platform) 
     40var chromeOS = /\bCrOS\b/.test(userAgent) 
     41var windows = /win/i.test(platform) 
     42 
     43var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/) 
     44if (presto_version) { presto_version = Number(presto_version[1]) } 
     45if (presto_version && presto_version >= 15) { presto = false; webkit = true } 
    4646// Some browsers use the wrong event properties to signal cmd/ctrl on OS X 
    47 var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); 
    48 var captureRightClick = gecko || (ie && ie_version >= 9); 
     47var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)) 
     48var captureRightClick = gecko || (ie && ie_version >= 9) 
    4949 
    5050function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") } 
    5151 
    5252var rmClass = function(node, cls) { 
    53   var current = node.className; 
    54   var match = classTest(cls).exec(current); 
     53  var current = node.className 
     54  var match = classTest(cls).exec(current) 
    5555  if (match) { 
    56     var after = current.slice(match.index + match[0].length); 
    57     node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); 
    58   } 
    59 }; 
     56    var after = current.slice(match.index + match[0].length) 
     57    node.className = current.slice(0, match.index) + (after ? match[1] + after : "") 
     58  } 
     59} 
    6060 
    6161function removeChildren(e) { 
    6262  for (var count = e.childNodes.length; count > 0; --count) 
    63     { e.removeChild(e.firstChild); } 
     63    { e.removeChild(e.firstChild) } 
    6464  return e 
    6565} 
     
    7070 
    7171function elt(tag, content, className, style) { 
    72   var e = document.createElement(tag); 
    73   if (className) { e.className = className; } 
    74   if (style) { e.style.cssText = style; } 
    75   if (typeof content == "string") { e.appendChild(document.createTextNode(content)); } 
    76   else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } } 
     72  var e = document.createElement(tag) 
     73  if (className) { e.className = className } 
     74  if (style) { e.style.cssText = style } 
     75  if (typeof content == "string") { e.appendChild(document.createTextNode(content)) } 
     76  else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]) } } 
    7777  return e 
    7878} 
    7979// wrapper for elt, which removes the elt from the accessibility tree 
    8080function eltP(tag, content, className, style) { 
    81   var e = elt(tag, content, className, style); 
    82   e.setAttribute("role", "presentation"); 
     81  var e = elt(tag, content, className, style) 
     82  e.setAttribute("role", "presentation") 
    8383  return e 
    8484} 
    8585 
    86 var range; 
     86var range 
    8787if (document.createRange) { range = function(node, start, end, endNode) { 
    88   var r = document.createRange(); 
    89   r.setEnd(endNode || node, end); 
    90   r.setStart(node, start); 
     88  var r = document.createRange() 
     89  r.setEnd(endNode || node, end) 
     90  r.setStart(node, start) 
    9191  return r 
    92 }; } 
     92} } 
    9393else { range = function(node, start, end) { 
    94   var r = document.body.createTextRange(); 
    95   try { r.moveToElementText(node.parentNode); } 
     94  var r = document.body.createTextRange() 
     95  try { r.moveToElementText(node.parentNode) } 
    9696  catch(e) { return r } 
    97   r.collapse(true); 
    98   r.moveEnd("character", end); 
    99   r.moveStart("character", start); 
     97  r.collapse(true) 
     98  r.moveEnd("character", end) 
     99  r.moveStart("character", start) 
    100100  return r 
    101 }; } 
     101} } 
    102102 
    103103function contains(parent, child) { 
    104104  if (child.nodeType == 3) // Android browser always returns false when child is a textnode 
    105     { child = child.parentNode; } 
     105    { child = child.parentNode } 
    106106  if (parent.contains) 
    107107    { return parent.contains(child) } 
    108108  do { 
    109     if (child.nodeType == 11) { child = child.host; } 
     109    if (child.nodeType == 11) { child = child.host } 
    110110    if (child == parent) { return true } 
    111111  } while (child = child.parentNode) 
     
    116116  // IE < 10 will throw when accessed while the page is loading or in an iframe. 
    117117  // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable. 
    118   var activeElement; 
     118  var activeElement 
    119119  try { 
    120     activeElement = document.activeElement; 
     120    activeElement = document.activeElement 
    121121  } catch(e) { 
    122     activeElement = document.body || null; 
     122    activeElement = document.body || null 
    123123  } 
    124124  while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) 
    125     { activeElement = activeElement.shadowRoot.activeElement; } 
     125    { activeElement = activeElement.shadowRoot.activeElement } 
    126126  return activeElement 
    127127} 
    128128 
    129129function addClass(node, cls) { 
    130   var current = node.className; 
    131   if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; } 
     130  var current = node.className 
     131  if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls } 
    132132} 
    133133function joinClasses(a, b) { 
    134   var as = a.split(" "); 
     134  var as = a.split(" ") 
    135135  for (var i = 0; i < as.length; i++) 
    136     { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } } 
     136    { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i] } } 
    137137  return b 
    138138} 
    139139 
    140 var selectInput = function(node) { node.select(); }; 
     140var selectInput = function(node) { node.select() } 
    141141if (ios) // Mobile Safari apparently has a bug where select() is broken. 
    142   { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; } 
     142  { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length } } 
    143143else if (ie) // Suppress mysterious IE10 errors 
    144   { selectInput = function(node) { try { node.select(); } catch(_e) {} }; } 
     144  { selectInput = function(node) { try { node.select() } catch(_e) {} } } 
    145145 
    146146function bind(f) { 
    147   var args = Array.prototype.slice.call(arguments, 1); 
     147  var args = Array.prototype.slice.call(arguments, 1) 
    148148  return function(){return f.apply(null, args)} 
    149149} 
    150150 
    151151function copyObj(obj, target, overwrite) { 
    152   if (!target) { target = {}; } 
     152  if (!target) { target = {} } 
    153153  for (var prop in obj) 
    154154    { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) 
    155       { target[prop] = obj[prop]; } } 
     155      { target[prop] = obj[prop] } } 
    156156  return target 
    157157} 
     
    161161function countColumn(string, end, tabSize, startIndex, startValue) { 
    162162  if (end == null) { 
    163     end = string.search(/[^\s\u00a0]/); 
    164     if (end == -1) { end = string.length; } 
     163    end = string.search(/[^\s\u00a0]/) 
     164    if (end == -1) { end = string.length } 
    165165  } 
    166166  for (var i = startIndex || 0, n = startValue || 0;;) { 
    167     var nextTab = string.indexOf("\t", i); 
     167    var nextTab = string.indexOf("\t", i) 
    168168    if (nextTab < 0 || nextTab >= end) 
    169169      { return n + (end - i) } 
    170     n += nextTab - i; 
    171     n += tabSize - (n % tabSize); 
    172     i = nextTab + 1; 
    173   } 
    174 } 
    175  
    176 var Delayed = function() {this.id = null;}; 
     170    n += nextTab - i 
     171    n += tabSize - (n % tabSize) 
     172    i = nextTab + 1 
     173  } 
     174} 
     175 
     176var Delayed = function() {this.id = null}; 
    177177Delayed.prototype.set = function (ms, f) { 
    178   clearTimeout(this.id); 
    179   this.id = setTimeout(f, ms); 
     178  clearTimeout(this.id) 
     179  this.id = setTimeout(f, ms) 
    180180}; 
    181181 
     
    187187 
    188188// Number of pixels added to scroller and sizer to hide scrollbar 
    189 var scrollerGap = 30; 
     189var scrollerGap = 30 
    190190 
    191191// Returned or thrown by various protocols to signal 'I'm not 
    192192// handling this'. 
    193 var Pass = {toString: function(){return "CodeMirror.Pass"}}; 
     193var Pass = {toString: function(){return "CodeMirror.Pass"}} 
    194194 
    195195// Reused option objects for setSelection & friends 
     
    197197var sel_mouse = {origin: "*mouse"}; 
    198198var sel_move = {origin: "+move"}; 
    199  
    200199// The inverse of countColumn -- find the offset that corresponds to 
    201200// a particular column. 
    202201function findColumn(string, goal, tabSize) { 
    203202  for (var pos = 0, col = 0;;) { 
    204     var nextTab = string.indexOf("\t", pos); 
    205     if (nextTab == -1) { nextTab = string.length; } 
    206     var skipped = nextTab - pos; 
     203    var nextTab = string.indexOf("\t", pos) 
     204    if (nextTab == -1) { nextTab = string.length } 
     205    var skipped = nextTab - pos 
    207206    if (nextTab == string.length || col + skipped >= goal) 
    208207      { return pos + Math.min(skipped, goal - col) } 
    209     col += nextTab - pos; 
    210     col += tabSize - (col % tabSize); 
    211     pos = nextTab + 1; 
     208    col += nextTab - pos 
     209    col += tabSize - (col % tabSize) 
     210    pos = nextTab + 1 
    212211    if (col >= goal) { return pos } 
    213212  } 
    214213} 
    215214 
    216 var spaceStrs = [""]; 
     215var spaceStrs = [""] 
    217216function spaceStr(n) { 
    218217  while (spaceStrs.length <= n) 
    219     { spaceStrs.push(lst(spaceStrs) + " "); } 
     218    { spaceStrs.push(lst(spaceStrs) + " ") } 
    220219  return spaceStrs[n] 
    221220} 
     
    224223 
    225224function map(array, f) { 
    226   var out = []; 
    227   for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); } 
     225  var out = [] 
     226  for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i) } 
    228227  return out 
    229228} 
    230229 
    231230function insertSorted(array, value, score) { 
    232   var pos = 0, priority = score(value); 
    233   while (pos < array.length && score(array[pos]) <= priority) { pos++; } 
    234   array.splice(pos, 0, value); 
     231  var pos = 0, priority = score(value) 
     232  while (pos < array.length && score(array[pos]) <= priority) { pos++ } 
     233  array.splice(pos, 0, value) 
    235234} 
    236235 
     
    238237 
    239238function createObj(base, props) { 
    240   var inst; 
     239  var inst 
    241240  if (Object.create) { 
    242     inst = Object.create(base); 
     241    inst = Object.create(base) 
    243242  } else { 
    244     nothing.prototype = base; 
    245     inst = new nothing(); 
    246   } 
    247   if (props) { copyObj(props, inst); } 
     243    nothing.prototype = base 
     244    inst = new nothing() 
     245  } 
     246  if (props) { copyObj(props, inst) } 
    248247  return inst 
    249248} 
    250249 
    251 var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; 
     250var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/ 
    252251function isWordCharBasic(ch) { 
    253252  return /\w/.test(ch) || ch > "\x80" && 
     
    270269// since some scripts/fonts/browsers also treat other configurations 
    271270// of code points as a group. 
    272 var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; 
     271var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/ 
    273272function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) } 
    274273 
    275274// Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range. 
    276275function skipExtendingChars(str, pos, dir) { 
    277   while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; } 
     276  while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir } 
    278277  return pos 
    279278} 
    280279 
    281280// Returns the value from the range [`from`; `to`] that satisfies 
    282 // `pred` and is closest to `from`. Assumes that at least `to` satisfies `pred`. 
     281// `pred` and is closest to `from`. Assumes that at least `to` 
     282// satisfies `pred`. Supports `from` being greater than `to`. 
    283283function findFirst(pred, from, to) { 
     284  // At any point we are certain `to` satisfies `pred`, don't know 
     285  // whether `from` does. 
     286  var dir = from > to ? -1 : 1 
    284287  for (;;) { 
    285     if (Math.abs(from - to) <= 1) { return pred(from) ? from : to } 
    286     var mid = Math.floor((from + to) / 2); 
    287     if (pred(mid)) { to = mid; } 
    288     else { from = mid; } 
     288    if (from == to) { return from } 
     289    var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF) 
     290    if (mid == from) { return pred(mid) ? from : to } 
     291    if (pred(mid)) { to = mid } 
     292    else { from = mid + dir } 
    289293  } 
    290294} 
     
    295299 
    296300function Display(place, doc, input) { 
    297   var d = this; 
    298   this.input = input; 
     301  var d = this 
     302  this.input = input 
    299303 
    300304  // Covers bottom-right square when both scrollbars are present. 
    301   d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); 
    302   d.scrollbarFiller.setAttribute("cm-not-content", "true"); 
     305  d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler") 
     306  d.scrollbarFiller.setAttribute("cm-not-content", "true") 
    303307  // Covers bottom of gutter when coverGutterNextToScrollbar is on 
    304308  // and h scrollbar is present. 
    305   d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); 
    306   d.gutterFiller.setAttribute("cm-not-content", "true"); 
     309  d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler") 
     310  d.gutterFiller.setAttribute("cm-not-content", "true") 
    307311  // Will contain the actual code, positioned to cover the viewport. 
    308   d.lineDiv = eltP("div", null, "CodeMirror-code"); 
     312  d.lineDiv = eltP("div", null, "CodeMirror-code") 
    309313  // Elements are added to these to represent selection and cursors. 
    310   d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); 
    311   d.cursorDiv = elt("div", null, "CodeMirror-cursors"); 
     314  d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1") 
     315  d.cursorDiv = elt("div", null, "CodeMirror-cursors") 
    312316  // A visibility: hidden element used to find the size of things. 
    313   d.measure = elt("div", null, "CodeMirror-measure"); 
     317  d.measure = elt("div", null, "CodeMirror-measure") 
    314318  // When lines outside of the viewport are measured, they are drawn in this. 
    315   d.lineMeasure = elt("div", null, "CodeMirror-measure"); 
     319  d.lineMeasure = elt("div", null, "CodeMirror-measure") 
    316320  // Wraps everything that needs to exist inside the vertically-padded coordinate system 
    317321  d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], 
    318                     null, "position: relative; outline: none"); 
    319   var lines = eltP("div", [d.lineSpace], "CodeMirror-lines"); 
     322                    null, "position: relative; outline: none") 
     323  var lines = eltP("div", [d.lineSpace], "CodeMirror-lines") 
    320324  // Moved around its parent to cover visible view. 
    321   d.mover = elt("div", [lines], null, "position: relative"); 
     325  d.mover = elt("div", [lines], null, "position: relative") 
    322326  // Set to the height of the document, allowing scrolling. 
    323   d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); 
    324   d.sizerWidth = null; 
     327  d.sizer = elt("div", [d.mover], "CodeMirror-sizer") 
     328  d.sizerWidth = null 
    325329  // Behavior of elts with overflow: auto and padding is 
    326330  // inconsistent across browsers. This is used to ensure the 
    327331  // scrollable area is big enough. 
    328   d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); 
     332  d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;") 
    329333  // Will contain the gutters, if any. 
    330   d.gutters = elt("div", null, "CodeMirror-gutters"); 
    331   d.lineGutter = null; 
     334  d.gutters = elt("div", null, "CodeMirror-gutters") 
     335  d.lineGutter = null 
    332336  // Actual scrollable element. 
    333   d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); 
    334   d.scroller.setAttribute("tabIndex", "-1"); 
     337  d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll") 
     338  d.scroller.setAttribute("tabIndex", "-1") 
    335339  // The element in which the editor lives. 
    336   d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); 
     340  d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror") 
    337341 
    338342  // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) 
    339   if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } 
    340   if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; } 
     343  if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 } 
     344  if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true } 
    341345 
    342346  if (place) { 
    343     if (place.appendChild) { place.appendChild(d.wrapper); } 
    344     else { place(d.wrapper); } 
     347    if (place.appendChild) { place.appendChild(d.wrapper) } 
     348    else { place(d.wrapper) } 
    345349  } 
    346350 
    347351  // Current rendered range (may be bigger than the view window). 
    348   d.viewFrom = d.viewTo = doc.first; 
    349   d.reportedViewFrom = d.reportedViewTo = doc.first; 
     352  d.viewFrom = d.viewTo = doc.first 
     353  d.reportedViewFrom = d.reportedViewTo = doc.first 
    350354  // Information about the rendered lines. 
    351   d.view = []; 
    352   d.renderedView = null; 
     355  d.view = [] 
     356  d.renderedView = null 
    353357  // Holds info about a single rendered line when it was rendered 
    354358  // for measurement, while not in view. 
    355   d.externalMeasured = null; 
     359  d.externalMeasured = null 
    356360  // Empty space (in pixels) above the view 
    357   d.viewOffset = 0; 
    358   d.lastWrapHeight = d.lastWrapWidth = 0; 
    359   d.updateLineNumbers = null; 
    360  
    361   d.nativeBarWidth = d.barHeight = d.barWidth = 0; 
    362   d.scrollbarsClipped = false; 
     361  d.viewOffset = 0 
     362  d.lastWrapHeight = d.lastWrapWidth = 0 
     363  d.updateLineNumbers = null 
     364 
     365  d.nativeBarWidth = d.barHeight = d.barWidth = 0 
     366  d.scrollbarsClipped = false 
    363367 
    364368  // Used to only resize the line number gutter when necessary (when 
    365369  // the amount of lines crosses a boundary that makes its width change) 
    366   d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; 
     370  d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null 
    367371  // Set to true when a non-horizontal-scrolling line widget is 
    368372  // added. As an optimization, line widget aligning is skipped when 
    369373  // this is false. 
    370   d.alignWidgets = false; 
    371  
    372   d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; 
     374  d.alignWidgets = false 
     375 
     376  d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null 
    373377 
    374378  // Tracks the maximum line length so that the horizontal scrollbar 
    375379  // can be kept static when scrolling. 
    376   d.maxLine = null; 
    377   d.maxLineLength = 0; 
    378   d.maxLineChanged = false; 
     380  d.maxLine = null 
     381  d.maxLineLength = 0 
     382  d.maxLineChanged = false 
    379383 
    380384  // Used for measuring wheel scrolling granularity 
    381   d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; 
     385  d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null 
    382386 
    383387  // True when shift is held down. 
    384   d.shift = false; 
     388  d.shift = false 
    385389 
    386390  // Used to track whether anything happened since the context menu 
    387391  // was opened. 
    388   d.selForContextMenu = null; 
    389  
    390   d.activeTouch = null; 
    391  
    392   input.init(d); 
     392  d.selForContextMenu = null 
     393 
     394  d.activeTouch = null 
     395 
     396  input.init(d) 
    393397} 
    394398 
    395399// Find the line object corresponding to the given line number. 
    396400function getLine(doc, n) { 
    397   n -= doc.first; 
     401  n -= doc.first 
    398402  if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") } 
    399   var chunk = doc; 
     403  var chunk = doc 
    400404  while (!chunk.lines) { 
    401405    for (var i = 0;; ++i) { 
    402       var child = chunk.children[i], sz = child.chunkSize(); 
     406      var child = chunk.children[i], sz = child.chunkSize() 
    403407      if (n < sz) { chunk = child; break } 
    404       n -= sz; 
     408      n -= sz 
    405409    } 
    406410  } 
     
    411415// strings. 
    412416function getBetween(doc, start, end) { 
    413   var out = [], n = start.line; 
     417  var out = [], n = start.line 
    414418  doc.iter(start.line, end.line + 1, function (line) { 
    415     var text = line.text; 
    416     if (n == end.line) { text = text.slice(0, end.ch); } 
    417     if (n == start.line) { text = text.slice(start.ch); } 
    418     out.push(text); 
    419     ++n; 
    420   }); 
     419    var text = line.text 
     420    if (n == end.line) { text = text.slice(0, end.ch) } 
     421    if (n == start.line) { text = text.slice(start.ch) } 
     422    out.push(text) 
     423    ++n 
     424  }) 
    421425  return out 
    422426} 
    423427// Get the lines between from and to, as array of strings. 
    424428function getLines(doc, from, to) { 
    425   var out = []; 
    426   doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value 
     429  var out = [] 
     430  doc.iter(from, to, function (line) { out.push(line.text) }) // iter aborts when callback returns truthy value 
    427431  return out 
    428432} 
     
    431435// upwards to parent nodes. 
    432436function updateLineHeight(line, height) { 
    433   var diff = height - line.height; 
    434   if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } } 
     437  var diff = height - line.height 
     438  if (diff) { for (var n = line; n; n = n.parent) { n.height += diff } } 
    435439} 
    436440 
     
    439443function lineNo(line) { 
    440444  if (line.parent == null) { return null } 
    441   var cur = line.parent, no = indexOf(cur.lines, line); 
     445  var cur = line.parent, no = indexOf(cur.lines, line) 
    442446  for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { 
    443447    for (var i = 0;; ++i) { 
    444448      if (chunk.children[i] == cur) { break } 
    445       no += chunk.children[i].chunkSize(); 
     449      no += chunk.children[i].chunkSize() 
    446450    } 
    447451  } 
     
    452456// information in the document tree. 
    453457function lineAtHeight(chunk, h) { 
    454   var n = chunk.first; 
     458  var n = chunk.first 
    455459  outer: do { 
    456460    for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) { 
    457       var child = chunk.children[i$1], ch = child.height; 
     461      var child = chunk.children[i$1], ch = child.height 
    458462      if (h < ch) { chunk = child; continue outer } 
    459       h -= ch; 
    460       n += child.chunkSize(); 
     463      h -= ch 
     464      n += child.chunkSize() 
    461465    } 
    462466    return n 
    463467  } while (!chunk.lines) 
    464   var i = 0; 
     468  var i = 0 
    465469  for (; i < chunk.lines.length; ++i) { 
    466     var line = chunk.lines[i], lh = line.height; 
     470    var line = chunk.lines[i], lh = line.height 
    467471    if (h < lh) { break } 
    468     h -= lh; 
     472    h -= lh 
    469473  } 
    470474  return n + i 
     
    482486 
    483487  if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) } 
    484   this.line = line; 
    485   this.ch = ch; 
    486   this.sticky = sticky; 
     488  this.line = line 
     489  this.ch = ch 
     490  this.sticky = sticky 
    487491} 
    488492 
     
    502506function clipPos(doc, pos) { 
    503507  if (pos.line < doc.first) { return Pos(doc.first, 0) } 
    504   var last = doc.first + doc.size - 1; 
     508  var last = doc.first + doc.size - 1 
    505509  if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) } 
    506510  return clipToLen(pos, getLine(doc, pos.line).text.length) 
    507511} 
    508512function clipToLen(pos, linelen) { 
    509   var ch = pos.ch; 
     513  var ch = pos.ch 
    510514  if (ch == null || ch > linelen) { return Pos(pos.line, linelen) } 
    511515  else if (ch < 0) { return Pos(pos.line, 0) } 
     
    513517} 
    514518function clipPosArray(doc, array) { 
    515   var out = []; 
    516   for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); } 
     519  var out = [] 
     520  for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]) } 
    517521  return out 
    518522} 
     
    521525var sawReadOnlySpans = false; 
    522526var sawCollapsedSpans = false; 
    523  
    524527function seeReadOnlySpans() { 
    525   sawReadOnlySpans = true; 
     528  sawReadOnlySpans = true 
    526529} 
    527530 
    528531function seeCollapsedSpans() { 
    529   sawCollapsedSpans = true; 
     532  sawCollapsedSpans = true 
    530533} 
    531534 
     
    533536 
    534537function MarkedSpan(marker, from, to) { 
    535   this.marker = marker; 
    536   this.from = from; this.to = to; 
     538  this.marker = marker 
     539  this.from = from; this.to = to 
    537540} 
    538541 
     
    540543function getMarkedSpanFor(spans, marker) { 
    541544  if (spans) { for (var i = 0; i < spans.length; ++i) { 
    542     var span = spans[i]; 
     545    var span = spans[i] 
    543546    if (span.marker == marker) { return span } 
    544547  } } 
     
    547550// left (we don't store arrays for lines without spans). 
    548551function removeMarkedSpan(spans, span) { 
    549   var r; 
     552  var r 
    550553  for (var i = 0; i < spans.length; ++i) 
    551     { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } } 
     554    { if (spans[i] != span) { (r || (r = [])).push(spans[i]) } } 
    552555  return r 
    553556} 
    554557// Add a span to a line. 
    555558function addMarkedSpan(line, span) { 
    556   line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; 
    557   span.marker.attachLine(line); 
     559  line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span] 
     560  span.marker.attachLine(line) 
    558561} 
    559562 
     
    563566// undefined if nothing remains). 
    564567function markedSpansBefore(old, startCh, isInsert) { 
    565   var nw; 
     568  var nw 
    566569  if (old) { for (var i = 0; i < old.length; ++i) { 
    567     var span = old[i], marker = span.marker; 
    568     var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); 
     570    var span = old[i], marker = span.marker 
     571    var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh) 
    569572    if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { 
    570       var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); 
     573      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh) 
     574      ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)) 
    571575    } 
    572576  } } 
     
    574578} 
    575579function markedSpansAfter(old, endCh, isInsert) { 
    576   var nw; 
     580  var nw 
    577581  if (old) { for (var i = 0; i < old.length; ++i) { 
    578     var span = old[i], marker = span.marker; 
    579     var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); 
     582    var span = old[i], marker = span.marker 
     583    var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh) 
    580584    if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { 
    581       var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, 
    582                                             span.to == null ? null : span.to - endCh)); 
     585      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh) 
     586      ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, 
     587                                            span.to == null ? null : span.to - endCh)) 
    583588    } 
    584589  } } 
     
    594599function stretchSpansOverChange(doc, change) { 
    595600  if (change.full) { return null } 
    596   var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; 
    597   var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; 
     601  var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans 
     602  var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans 
    598603  if (!oldFirst && !oldLast) { return null } 
    599604 
    600   var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; 
     605  var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0 
    601606  // Get the spans that 'stick out' on both sides 
    602   var first = markedSpansBefore(oldFirst, startCh, isInsert); 
    603   var last = markedSpansAfter(oldLast, endCh, isInsert); 
     607  var first = markedSpansBefore(oldFirst, startCh, isInsert) 
     608  var last = markedSpansAfter(oldLast, endCh, isInsert) 
    604609 
    605610  // Next, merge those two ends 
    606   var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); 
     611  var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0) 
    607612  if (first) { 
    608613    // Fix up .to properties of first 
    609614    for (var i = 0; i < first.length; ++i) { 
    610       var span = first[i]; 
     615      var span = first[i] 
    611616      if (span.to == null) { 
    612         var found = getMarkedSpanFor(last, span.marker); 
    613         if (!found) { span.to = startCh; } 
    614         else if (sameLine) { span.to = found.to == null ? null : found.to + offset; } 
     617        var found = getMarkedSpanFor(last, span.marker) 
     618        if (!found) { span.to = startCh } 
     619        else if (sameLine) { span.to = found.to == null ? null : found.to + offset } 
    615620      } 
    616621    } 
     
    619624    // Fix up .from in last (or move them into first in case of sameLine) 
    620625    for (var i$1 = 0; i$1 < last.length; ++i$1) { 
    621       var span$1 = last[i$1]; 
    622       if (span$1.to != null) { span$1.to += offset; } 
     626      var span$1 = last[i$1] 
     627      if (span$1.to != null) { span$1.to += offset } 
    623628      if (span$1.from == null) { 
    624         var found$1 = getMarkedSpanFor(first, span$1.marker); 
     629        var found$1 = getMarkedSpanFor(first, span$1.marker) 
    625630        if (!found$1) { 
    626           span$1.from = offset; 
    627           if (sameLine) { (first || (first = [])).push(span$1); } 
     631          span$1.from = offset 
     632          if (sameLine) { (first || (first = [])).push(span$1) } 
    628633        } 
    629634      } else { 
    630         span$1.from += offset; 
    631         if (sameLine) { (first || (first = [])).push(span$1); } 
     635        span$1.from += offset 
     636        if (sameLine) { (first || (first = [])).push(span$1) } 
    632637      } 
    633638    } 
    634639  } 
    635640  // Make sure we didn't create any zero-length spans 
    636   if (first) { first = clearEmptySpans(first); } 
    637   if (last && last != first) { last = clearEmptySpans(last); } 
    638  
    639   var newMarkers = [first]; 
     641  if (first) { first = clearEmptySpans(first) } 
     642  if (last && last != first) { last = clearEmptySpans(last) } 
     643 
     644  var newMarkers = [first] 
    640645  if (!sameLine) { 
    641646    // Fill gap with whole-line-spans 
    642     var gap = change.text.length - 2, gapMarkers; 
     647    var gap = change.text.length - 2, gapMarkers 
    643648    if (gap > 0 && first) 
    644649      { for (var i$2 = 0; i$2 < first.length; ++i$2) 
    645650        { if (first[i$2].to == null) 
    646           { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } } } 
     651          { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)) } } } 
    647652    for (var i$3 = 0; i$3 < gap; ++i$3) 
    648       { newMarkers.push(gapMarkers); } 
    649     newMarkers.push(last); 
     653      { newMarkers.push(gapMarkers) } 
     654    newMarkers.push(last) 
    650655  } 
    651656  return newMarkers 
     
    656661function clearEmptySpans(spans) { 
    657662  for (var i = 0; i < spans.length; ++i) { 
    658     var span = spans[i]; 
     663    var span = spans[i] 
    659664    if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) 
    660       { spans.splice(i--, 1); } 
     665      { spans.splice(i--, 1) } 
    661666  } 
    662667  if (!spans.length) { return null } 
     
    666671// Used to 'clip' out readOnly ranges when making a change. 
    667672function removeReadOnlyRanges(doc, from, to) { 
    668   var markers = null; 
     673  var markers = null 
    669674  doc.iter(from.line, to.line + 1, function (line) { 
    670675    if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) { 
    671       var mark = line.markedSpans[i].marker; 
     676      var mark = line.markedSpans[i].marker 
    672677      if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) 
    673         { (markers || (markers = [])).push(mark); } 
     678        { (markers || (markers = [])).push(mark) } 
    674679    } } 
    675   }); 
     680  }) 
    676681  if (!markers) { return null } 
    677   var parts = [{from: from, to: to}]; 
     682  var parts = [{from: from, to: to}] 
    678683  for (var i = 0; i < markers.length; ++i) { 
    679     var mk = markers[i], m = mk.find(0); 
     684    var mk = markers[i], m = mk.find(0) 
    680685    for (var j = 0; j < parts.length; ++j) { 
    681       var p = parts[j]; 
     686      var p = parts[j] 
    682687      if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue } 
    683       var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); 
     688      var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to) 
    684689      if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) 
    685         { newParts.push({from: p.from, to: m.from}); } 
     690        { newParts.push({from: p.from, to: m.from}) } 
    686691      if (dto > 0 || !mk.inclusiveRight && !dto) 
    687         { newParts.push({from: m.to, to: p.to}); } 
    688       parts.splice.apply(parts, newParts); 
    689       j += newParts.length - 3; 
     692        { newParts.push({from: m.to, to: p.to}) } 
     693      parts.splice.apply(parts, newParts) 
     694      j += newParts.length - 3 
    690695    } 
    691696  } 
     
    695700// Connect or disconnect spans from a line. 
    696701function detachMarkedSpans(line) { 
    697   var spans = line.markedSpans; 
     702  var spans = line.markedSpans 
    698703  if (!spans) { return } 
    699704  for (var i = 0; i < spans.length; ++i) 
    700     { spans[i].marker.detachLine(line); } 
    701   line.markedSpans = null; 
     705    { spans[i].marker.detachLine(line) } 
     706  line.markedSpans = null 
    702707} 
    703708function attachMarkedSpans(line, spans) { 
    704709  if (!spans) { return } 
    705710  for (var i = 0; i < spans.length; ++i) 
    706     { spans[i].marker.attachLine(line); } 
    707   line.markedSpans = spans; 
     711    { spans[i].marker.attachLine(line) } 
     712  line.markedSpans = spans 
    708713} 
    709714 
     
    717722// comparing ids when the spans cover exactly the same range. 
    718723function compareCollapsedMarkers(a, b) { 
    719   var lenDiff = a.lines.length - b.lines.length; 
     724  var lenDiff = a.lines.length - b.lines.length 
    720725  if (lenDiff != 0) { return lenDiff } 
    721   var aPos = a.find(), bPos = b.find(); 
    722   var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); 
     726  var aPos = a.find(), bPos = b.find() 
     727  var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b) 
    723728  if (fromCmp) { return -fromCmp } 
    724   var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); 
     729  var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b) 
    725730  if (toCmp) { return toCmp } 
    726731  return b.id - a.id 
     
    730735// so, return the marker for that span. 
    731736function collapsedSpanAtSide(line, start) { 
    732   var sps = sawCollapsedSpans && line.markedSpans, found; 
     737  var sps = sawCollapsedSpans && line.markedSpans, found 
    733738  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { 
    734     sp = sps[i]; 
     739    sp = sps[i] 
    735740    if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && 
    736741        (!found || compareCollapsedMarkers(found, sp.marker) < 0)) 
    737       { found = sp.marker; } 
     742      { found = sp.marker } 
    738743  } } 
    739744  return found 
     
    741746function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } 
    742747function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } 
     748 
     749function collapsedSpanAround(line, ch) { 
     750  var sps = sawCollapsedSpans && line.markedSpans, found 
     751  if (sps) { for (var i = 0; i < sps.length; ++i) { 
     752    var sp = sps[i] 
     753    if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) && 
     754        (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker } 
     755  } } 
     756  return found 
     757} 
    743758 
    744759// Test whether there exists a collapsed span that partially 
    745760// overlaps (covers the start or end, but not both) of a new span. 
    746761// Such overlap is not allowed. 
    747 function conflictingCollapsedRange(doc, lineNo$$1, from, to, marker) { 
    748   var line = getLine(doc, lineNo$$1); 
    749   var sps = sawCollapsedSpans && line.markedSpans; 
     762function conflictingCollapsedRange(doc, lineNo, from, to, marker) { 
     763  var line = getLine(doc, lineNo) 
     764  var sps = sawCollapsedSpans && line.markedSpans 
    750765  if (sps) { for (var i = 0; i < sps.length; ++i) { 
    751     var sp = sps[i]; 
     766    var sp = sps[i] 
    752767    if (!sp.marker.collapsed) { continue } 
    753     var found = sp.marker.find(0); 
    754     var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); 
    755     var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); 
     768    var found = sp.marker.find(0) 
     769    var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker) 
     770    var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker) 
    756771    if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue } 
    757772    if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || 
     
    766781// given line is part of (usually that is the line itself). 
    767782function visualLine(line) { 
    768   var merged; 
     783  var merged 
    769784  while (merged = collapsedSpanAtStart(line)) 
    770     { line = merged.find(-1, true).line; } 
     785    { line = merged.find(-1, true).line } 
    771786  return line 
    772787} 
    773788 
    774789function visualLineEnd(line) { 
    775   var merged; 
     790  var merged 
    776791  while (merged = collapsedSpanAtEnd(line)) 
    777     { line = merged.find(1, true).line; } 
     792    { line = merged.find(1, true).line } 
    778793  return line 
    779794} 
     
    782797// started by the argument, or undefined if there are no such lines. 
    783798function visualLineContinued(line) { 
    784   var merged, lines; 
     799  var merged, lines 
    785800  while (merged = collapsedSpanAtEnd(line)) { 
    786801    line = merged.find(1, true).line 
    787     ;(lines || (lines = [])).push(line); 
     802    ;(lines || (lines = [])).push(line) 
    788803  } 
    789804  return lines 
     
    793808// given line number is part of. 
    794809function visualLineNo(doc, lineN) { 
    795   var line = getLine(doc, lineN), vis = visualLine(line); 
     810  var line = getLine(doc, lineN), vis = visualLine(line) 
    796811  if (line == vis) { return lineN } 
    797812  return lineNo(vis) 
     
    802817function visualLineEndNo(doc, lineN) { 
    803818  if (lineN > doc.lastLine()) { return lineN } 
    804   var line = getLine(doc, lineN), merged; 
     819  var line = getLine(doc, lineN), merged 
    805820  if (!lineIsHidden(doc, line)) { return lineN } 
    806821  while (merged = collapsedSpanAtEnd(line)) 
    807     { line = merged.find(1, true).line; } 
     822    { line = merged.find(1, true).line } 
    808823  return lineNo(line) + 1 
    809824} 
     
    813828// they are entirely covered by collapsed, non-widget span. 
    814829function lineIsHidden(doc, line) { 
    815   var sps = sawCollapsedSpans && line.markedSpans; 
     830  var sps = sawCollapsedSpans && line.markedSpans 
    816831  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { 
    817     sp = sps[i]; 
     832    sp = sps[i] 
    818833    if (!sp.marker.collapsed) { continue } 
    819834    if (sp.from == null) { return true } 
     
    825840function lineIsHiddenInner(doc, line, span) { 
    826841  if (span.to == null) { 
    827     var end = span.marker.find(1, true); 
     842    var end = span.marker.find(1, true) 
    828843    return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)) 
    829844  } 
     
    831846    { return true } 
    832847  for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) { 
    833     sp = line.markedSpans[i]; 
     848    sp = line.markedSpans[i] 
    834849    if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && 
    835850        (sp.to == null || sp.to != span.from) && 
     
    841856// Find the height above the given line. 
    842857function heightAtLine(lineObj) { 
    843   lineObj = visualLine(lineObj); 
    844  
    845   var h = 0, chunk = lineObj.parent; 
     858  lineObj = visualLine(lineObj) 
     859 
     860  var h = 0, chunk = lineObj.parent 
    846861  for (var i = 0; i < chunk.lines.length; ++i) { 
    847     var line = chunk.lines[i]; 
     862    var line = chunk.lines[i] 
    848863    if (line == lineObj) { break } 
    849     else { h += line.height; } 
     864    else { h += line.height } 
    850865  } 
    851866  for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { 
    852867    for (var i$1 = 0; i$1 < p.children.length; ++i$1) { 
    853       var cur = p.children[i$1]; 
     868      var cur = p.children[i$1] 
    854869      if (cur == chunk) { break } 
    855       else { h += cur.height; } 
     870      else { h += cur.height } 
    856871    } 
    857872  } 
     
    864879function lineLength(line) { 
    865880  if (line.height == 0) { return 0 } 
    866   var len = line.text.length, merged, cur = line; 
     881  var len = line.text.length, merged, cur = line 
    867882  while (merged = collapsedSpanAtStart(cur)) { 
    868     var found = merged.find(0, true); 
    869     cur = found.from.line; 
    870     len += found.from.ch - found.to.ch; 
    871   } 
    872   cur = line; 
     883    var found = merged.find(0, true) 
     884    cur = found.from.line 
     885    len += found.from.ch - found.to.ch 
     886  } 
     887  cur = line 
    873888  while (merged = collapsedSpanAtEnd(cur)) { 
    874     var found$1 = merged.find(0, true); 
    875     len -= cur.text.length - found$1.from.ch; 
    876     cur = found$1.to.line; 
    877     len += cur.text.length - found$1.to.ch; 
     889    var found$1 = merged.find(0, true) 
     890    len -= cur.text.length - found$1.from.ch 
     891    cur = found$1.to.line 
     892    len += cur.text.length - found$1.to.ch 
    878893  } 
    879894  return len 
     
    882897// Find the longest line in the document. 
    883898function findMaxLine(cm) { 
    884   var d = cm.display, doc = cm.doc; 
    885   d.maxLine = getLine(doc, doc.first); 
    886   d.maxLineLength = lineLength(d.maxLine); 
    887   d.maxLineChanged = true; 
     899  var d = cm.display, doc = cm.doc 
     900  d.maxLine = getLine(doc, doc.first) 
     901  d.maxLineLength = lineLength(d.maxLine) 
     902  d.maxLineChanged = true 
    888903  doc.iter(function (line) { 
    889     var len = lineLength(line); 
     904    var len = lineLength(line) 
    890905    if (len > d.maxLineLength) { 
    891       d.maxLineLength = len; 
    892       d.maxLine = line; 
    893     } 
    894   }); 
     906      d.maxLineLength = len 
     907      d.maxLine = line 
     908    } 
     909  }) 
    895910} 
    896911 
     
    898913 
    899914function iterateBidiSections(order, from, to, f) { 
    900   if (!order) { return f(from, to, "ltr") } 
    901   var found = false; 
     915  if (!order) { return f(from, to, "ltr", 0) } 
     916  var found = false 
    902917  for (var i = 0; i < order.length; ++i) { 
    903     var part = order[i]; 
     918    var part = order[i] 
    904919    if (part.from < to && part.to > from || from == to && part.to == from) { 
    905       f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); 
    906       found = true; 
    907     } 
    908   } 
    909   if (!found) { f(from, to, "ltr"); } 
    910 } 
    911  
    912 var bidiOther = null; 
     920      f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i) 
     921      found = true 
     922    } 
     923  } 
     924  if (!found) { f(from, to, "ltr") } 
     925} 
     926 
     927var bidiOther = null 
    913928function getBidiPartAt(order, ch, sticky) { 
    914   var found; 
    915   bidiOther = null; 
     929  var found 
     930  bidiOther = null 
    916931  for (var i = 0; i < order.length; ++i) { 
    917     var cur = order[i]; 
     932    var cur = order[i] 
    918933    if (cur.from < ch && cur.to > ch) { return i } 
    919934    if (cur.to == ch) { 
    920       if (cur.from != cur.to && sticky == "before") { found = i; } 
    921       else { bidiOther = i; } 
     935      if (cur.from != cur.to && sticky == "before") { found = i } 
     936      else { bidiOther = i } 
    922937    } 
    923938    if (cur.from == ch) { 
    924       if (cur.from != cur.to && sticky != "before") { found = i; } 
    925       else { bidiOther = i; } 
     939      if (cur.from != cur.to && sticky != "before") { found = i } 
     940      else { bidiOther = i } 
    926941    } 
    927942  } 
     
    954969var bidiOrdering = (function() { 
    955970  // Character types for codepoints 0 to 0xff 
    956   var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; 
     971  var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN" 
    957972  // Character types for codepoints 0x600 to 0x6f9 
    958   var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111"; 
     973  var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111" 
    959974  function charType(code) { 
    960975    if (code <= 0xf7) { return lowTypes.charAt(code) } 
     
    967982  } 
    968983 
    969   var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; 
    970   var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; 
     984  var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/ 
     985  var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/ 
    971986 
    972987  function BidiSpan(level, from, to) { 
    973     this.level = level; 
    974     this.from = from; this.to = to; 
     988    this.level = level 
     989    this.from = from; this.to = to 
    975990  } 
    976991 
    977992  return function(str, direction) { 
    978     var outerType = direction == "ltr" ? "L" : "R"; 
     993    var outerType = direction == "ltr" ? "L" : "R" 
    979994 
    980995    if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false } 
    981     var len = str.length, types = []; 
     996    var len = str.length, types = [] 
    982997    for (var i = 0; i < len; ++i) 
    983       { types.push(charType(str.charCodeAt(i))); } 
     998      { types.push(charType(str.charCodeAt(i))) } 
    984999 
    9851000    // W1. Examine each non-spacing mark (NSM) in the level run, and 
     
    9881003    // get the type of sor. 
    9891004    for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) { 
    990       var type = types[i$1]; 
    991       if (type == "m") { types[i$1] = prev; } 
    992       else { prev = type; } 
     1005      var type = types[i$1] 
     1006      if (type == "m") { types[i$1] = prev } 
     1007      else { prev = type } 
    9931008    } 
    9941009 
     
    9991014    // W3. Change all ALs to R. 
    10001015    for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) { 
    1001       var type$1 = types[i$2]; 
    1002       if (type$1 == "1" && cur == "r") { types[i$2] = "n"; } 
    1003       else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } } 
     1016      var type$1 = types[i$2] 
     1017      if (type$1 == "1" && cur == "r") { types[i$2] = "n" } 
     1018      else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R" } } 
    10041019    } 
    10051020 
     
    10081023    // two numbers of the same type changes to that type. 
    10091024    for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) { 
    1010       var type$2 = types[i$3]; 
    1011       if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1"; } 
     1025      var type$2 = types[i$3] 
     1026      if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1" } 
    10121027      else if (type$2 == "," && prev$1 == types[i$3+1] && 
    1013                (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; } 
    1014       prev$1 = type$2; 
     1028               (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1 } 
     1029      prev$1 = type$2 
    10151030    } 
    10161031 
     
    10201035    // Neutral. 
    10211036    for (var i$4 = 0; i$4 < len; ++i$4) { 
    1022       var type$3 = types[i$4]; 
    1023       if (type$3 == ",") { types[i$4] = "N"; } 
     1037      var type$3 = types[i$4] 
     1038      if (type$3 == ",") { types[i$4] = "N" } 
    10241039      else if (type$3 == "%") { 
    1025         var end = (void 0); 
     1040        var end = (void 0) 
    10261041        for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {} 
    1027         var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; 
    1028         for (var j = i$4; j < end; ++j) { types[j] = replace; } 
    1029         i$4 = end - 1; 
     1042        var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N" 
     1043        for (var j = i$4; j < end; ++j) { types[j] = replace } 
     1044        i$4 = end - 1 
    10301045      } 
    10311046    } 
     
    10351050    // found, then change the type of the European number to L. 
    10361051    for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) { 
    1037       var type$4 = types[i$5]; 
    1038       if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; } 
    1039       else if (isStrong.test(type$4)) { cur$1 = type$4; } 
     1052      var type$4 = types[i$5] 
     1053      if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L" } 
     1054      else if (isStrong.test(type$4)) { cur$1 = type$4 } 
    10401055    } 
    10411056 
     
    10481063    for (var i$6 = 0; i$6 < len; ++i$6) { 
    10491064      if (isNeutral.test(types[i$6])) { 
    1050         var end$1 = (void 0); 
     1065        var end$1 = (void 0) 
    10511066        for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {} 
    1052         var before = (i$6 ? types[i$6-1] : outerType) == "L"; 
    1053         var after = (end$1 < len ? types[end$1] : outerType) == "L"; 
    1054         var replace$1 = before == after ? (before ? "L" : "R") : outerType; 
    1055         for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; } 
    1056         i$6 = end$1 - 1; 
     1067        var before = (i$6 ? types[i$6-1] : outerType) == "L" 
     1068        var after = (end$1 < len ? types[end$1] : outerType) == "L" 
     1069        var replace$1 = before == after ? (before ? "L" : "R") : outerType 
     1070        for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1 } 
     1071        i$6 = end$1 - 1 
    10571072      } 
    10581073    } 
     
    10631078    // explicit embedding into account, we can build up the order on 
    10641079    // the fly, without following the level-based algorithm. 
    1065     var order = [], m; 
     1080    var order = [], m 
    10661081    for (var i$7 = 0; i$7 < len;) { 
    10671082      if (countsAsLeft.test(types[i$7])) { 
    1068         var start = i$7; 
     1083        var start = i$7 
    10691084        for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {} 
    1070         order.push(new BidiSpan(0, start, i$7)); 
     1085        order.push(new BidiSpan(0, start, i$7)) 
    10711086      } else { 
    1072         var pos = i$7, at = order.length; 
     1087        var pos = i$7, at = order.length 
    10731088        for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {} 
    10741089        for (var j$2 = pos; j$2 < i$7;) { 
    10751090          if (countsAsNum.test(types[j$2])) { 
    1076             if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); } 
    1077             var nstart = j$2; 
     1091            if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)) } 
     1092            var nstart = j$2 
    10781093            for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {} 
    1079             order.splice(at, 0, new BidiSpan(2, nstart, j$2)); 
    1080             pos = j$2; 
    1081           } else { ++j$2; } 
     1094            order.splice(at, 0, new BidiSpan(2, nstart, j$2)) 
     1095            pos = j$2 
     1096          } else { ++j$2 } 
    10821097        } 
    1083         if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); } 
     1098        if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) } 
    10841099      } 
    10851100    } 
    1086     if (order[0].level == 1 && (m = str.match(/^\s+/))) { 
    1087       order[0].from = m[0].length; 
    1088       order.unshift(new BidiSpan(0, 0, m[0].length)); 
    1089     } 
    1090     if (lst(order).level == 1 && (m = str.match(/\s+$/))) { 
    1091       lst(order).to -= m[0].length; 
    1092       order.push(new BidiSpan(0, len - m[0].length, len)); 
     1101    if (direction == "ltr") { 
     1102      if (order[0].level == 1 && (m = str.match(/^\s+/))) { 
     1103        order[0].from = m[0].length 
     1104        order.unshift(new BidiSpan(0, 0, m[0].length)) 
     1105      } 
     1106      if (lst(order).level == 1 && (m = str.match(/\s+$/))) { 
     1107        lst(order).to -= m[0].length 
     1108        order.push(new BidiSpan(0, len - m[0].length, len)) 
     1109      } 
    10931110    } 
    10941111 
    10951112    return direction == "rtl" ? order.reverse() : order 
    10961113  } 
    1097 })(); 
     1114})() 
    10981115 
    10991116// Get the bidi ordering for the given line (and cache it). Returns 
     
    11011118// BidiSpan objects otherwise. 
    11021119function getOrder(line, direction) { 
    1103   var order = line.order; 
    1104   if (order == null) { order = line.order = bidiOrdering(line.text, direction); } 
     1120  var order = line.order 
     1121  if (order == null) { order = line.order = bidiOrdering(line.text, direction) } 
    11051122  return order 
    1106 } 
    1107  
    1108 function moveCharLogically(line, ch, dir) { 
    1109   var target = skipExtendingChars(line.text, ch + dir, dir); 
    1110   return target < 0 || target > line.text.length ? null : target 
    1111 } 
    1112  
    1113 function moveLogically(line, start, dir) { 
    1114   var ch = moveCharLogically(line, start.ch, dir); 
    1115   return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") 
    1116 } 
    1117  
    1118 function endOfLine(visually, cm, lineObj, lineNo, dir) { 
    1119   if (visually) { 
    1120     var order = getOrder(lineObj, cm.doc.direction); 
    1121     if (order) { 
    1122       var part = dir < 0 ? lst(order) : order[0]; 
    1123       var moveInStorageOrder = (dir < 0) == (part.level == 1); 
    1124       var sticky = moveInStorageOrder ? "after" : "before"; 
    1125       var ch; 
    1126       // With a wrapped rtl chunk (possibly spanning multiple bidi parts), 
    1127       // it could be that the last bidi part is not on the last visual line, 
    1128       // since visual lines contain content order-consecutive chunks. 
    1129       // Thus, in rtl, we are looking for the first (content-order) character 
    1130       // in the rtl chunk that is on the last line (that is, the same line 
    1131       // as the last (content-order) character). 
    1132       if (part.level > 0) { 
    1133         var prep = prepareMeasureForLine(cm, lineObj); 
    1134         ch = dir < 0 ? lineObj.text.length - 1 : 0; 
    1135         var targetTop = measureCharPrepared(cm, prep, ch).top; 
    1136         ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch); 
    1137         if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1, true); } 
    1138       } else { ch = dir < 0 ? part.to : part.from; } 
    1139       return new Pos(lineNo, ch, sticky) 
    1140     } 
    1141   } 
    1142   return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") 
    1143 } 
    1144  
    1145 function moveVisually(cm, line, start, dir) { 
    1146   var bidi = getOrder(line, cm.doc.direction); 
    1147   if (!bidi) { return moveLogically(line, start, dir) } 
    1148   if (start.ch >= line.text.length) { 
    1149     start.ch = line.text.length; 
    1150     start.sticky = "before"; 
    1151   } else if (start.ch <= 0) { 
    1152     start.ch = 0; 
    1153     start.sticky = "after"; 
    1154   } 
    1155   var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]; 
    1156   if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { 
    1157     // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, 
    1158     // nothing interesting happens. 
    1159     return moveLogically(line, start, dir) 
    1160   } 
    1161  
    1162   var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }; 
    1163   var prep; 
    1164   var getWrappedLineExtent = function (ch) { 
    1165     if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} } 
    1166     prep = prep || prepareMeasureForLine(cm, line); 
    1167     return wrappedLineExtentChar(cm, line, prep, ch) 
    1168   }; 
    1169   var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch); 
    1170  
    1171   if (cm.doc.direction == "rtl" || part.level == 1) { 
    1172     var moveInStorageOrder = (part.level == 1) == (dir < 0); 
    1173     var ch = mv(start, moveInStorageOrder ? 1 : -1); 
    1174     if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { 
    1175       // Case 2: We move within an rtl part or in an rtl editor on the same visual line 
    1176       var sticky = moveInStorageOrder ? "before" : "after"; 
    1177       return new Pos(start.line, ch, sticky) 
    1178     } 
    1179   } 
    1180  
    1181   // Case 3: Could not move within this bidi part in this visual line, so leave 
    1182   // the current bidi part 
    1183  
    1184   var searchInVisualLine = function (partPos, dir, wrappedLineExtent) { 
    1185     var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder 
    1186       ? new Pos(start.line, mv(ch, 1), "before") 
    1187       : new Pos(start.line, ch, "after"); }; 
    1188  
    1189     for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { 
    1190       var part = bidi[partPos]; 
    1191       var moveInStorageOrder = (dir > 0) == (part.level != 1); 
    1192       var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1); 
    1193       if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) } 
    1194       ch = moveInStorageOrder ? part.from : mv(part.to, -1); 
    1195       if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) } 
    1196     } 
    1197   }; 
    1198  
    1199   // Case 3a: Look for other bidi parts on the same visual line 
    1200   var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent); 
    1201   if (res) { return res } 
    1202  
    1203   // Case 3b: Look for other bidi parts on the next visual line 
    1204   var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1); 
    1205   if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { 
    1206     res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)); 
    1207     if (res) { return res } 
    1208   } 
    1209  
    1210   // Case 4: Nowhere to move 
    1211   return null 
    12121123} 
    12131124 
     
    12171128// registering native DOM handlers. 
    12181129 
    1219 var noHandlers = []; 
     1130var noHandlers = [] 
    12201131 
    12211132var on = function(emitter, type, f) { 
    12221133  if (emitter.addEventListener) { 
    1223     emitter.addEventListener(type, f, false); 
     1134    emitter.addEventListener(type, f, false) 
    12241135  } else if (emitter.attachEvent) { 
    1225     emitter.attachEvent("on" + type, f); 
     1136    emitter.attachEvent("on" + type, f) 
    12261137  } else { 
    1227     var map$$1 = emitter._handlers || (emitter._handlers = {}); 
    1228     map$$1[type] = (map$$1[type] || noHandlers).concat(f); 
    1229   } 
    1230 }; 
     1138    var map = emitter._handlers || (emitter._handlers = {}) 
     1139    map[type] = (map[type] || noHandlers).concat(f) 
     1140  } 
     1141} 
    12311142 
    12321143function getHandlers(emitter, type) { 
     
    12361147function off(emitter, type, f) { 
    12371148  if (emitter.removeEventListener) { 
    1238     emitter.removeEventListener(type, f, false); 
     1149    emitter.removeEventListener(type, f, false) 
    12391150  } else if (emitter.detachEvent) { 
    1240     emitter.detachEvent("on" + type, f); 
     1151    emitter.detachEvent("on" + type, f) 
    12411152  } else { 
    1242     var map$$1 = emitter._handlers, arr = map$$1 && map$$1[type]; 
     1153    var map = emitter._handlers, arr = map && map[type] 
    12431154    if (arr) { 
    1244       var index = indexOf(arr, f); 
     1155      var index = indexOf(arr, f) 
    12451156      if (index > -1) 
    1246         { map$$1[type] = arr.slice(0, index).concat(arr.slice(index + 1)); } 
     1157        { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)) } 
    12471158    } 
    12481159  } 
     
    12501161 
    12511162function signal(emitter, type /*, values...*/) { 
    1252   var handlers = getHandlers(emitter, type); 
     1163  var handlers = getHandlers(emitter, type) 
    12531164  if (!handlers.length) { return } 
    1254   var args = Array.prototype.slice.call(arguments, 2); 
    1255   for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); } 
     1165  var args = Array.prototype.slice.call(arguments, 2) 
     1166  for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args) } 
    12561167} 
    12571168 
     
    12611172function signalDOMEvent(cm, e, override) { 
    12621173  if (typeof e == "string") 
    1263     { e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; } 
    1264   signal(cm, override || e.type, cm, e); 
     1174    { e = {type: e, preventDefault: function() { this.defaultPrevented = true }} } 
     1175  signal(cm, override || e.type, cm, e) 
    12651176  return e_defaultPrevented(e) || e.codemirrorIgnore 
    12661177} 
    12671178 
    12681179function signalCursorActivity(cm) { 
    1269   var arr = cm._handlers && cm._handlers.cursorActivity; 
     1180  var arr = cm._handlers && cm._handlers.cursorActivity 
    12701181  if (!arr) { return } 
    1271   var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); 
     1182  var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []) 
    12721183  for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1) 
    1273     { set.push(arr[i]); } } 
     1184    { set.push(arr[i]) } } 
    12741185} 
    12751186 
     
    12811192// registering events on such objects more convenient. 
    12821193function eventMixin(ctor) { 
    1283   ctor.prototype.on = function(type, f) {on(this, type, f);}; 
    1284   ctor.prototype.off = function(type, f) {off(this, type, f);}; 
     1194  ctor.prototype.on = function(type, f) {on(this, type, f)} 
     1195  ctor.prototype.off = function(type, f) {off(this, type, f)} 
    12851196} 
    12861197 
     
    12891200 
    12901201function e_preventDefault(e) { 
    1291   if (e.preventDefault) { e.preventDefault(); } 
    1292   else { e.returnValue = false; } 
     1202  if (e.preventDefault) { e.preventDefault() } 
     1203  else { e.returnValue = false } 
    12931204} 
    12941205function e_stopPropagation(e) { 
    1295   if (e.stopPropagation) { e.stopPropagation(); } 
    1296   else { e.cancelBubble = true; } 
     1206  if (e.stopPropagation) { e.stopPropagation() } 
     1207  else { e.cancelBubble = true } 
    12971208} 
    12981209function e_defaultPrevented(e) { 
    12991210  return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false 
    13001211} 
    1301 function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);} 
     1212function e_stop(e) {e_preventDefault(e); e_stopPropagation(e)} 
    13021213 
    13031214function e_target(e) {return e.target || e.srcElement} 
    13041215function e_button(e) { 
    1305   var b = e.which; 
     1216  var b = e.which 
    13061217  if (b == null) { 
    1307     if (e.button & 1) { b = 1; } 
    1308     else if (e.button & 2) { b = 3; } 
    1309     else if (e.button & 4) { b = 2; } 
    1310   } 
    1311   if (mac && e.ctrlKey && b == 1) { b = 3; } 
     1218    if (e.button & 1) { b = 1 } 
     1219    else if (e.button & 2) { b = 3 } 
     1220    else if (e.button & 4) { b = 2 } 
     1221  } 
     1222  if (mac && e.ctrlKey && b == 1) { b = 3 } 
    13121223  return b 
    13131224} 
     
    13181229  // couldn't get it to work yet. 
    13191230  if (ie && ie_version < 9) { return false } 
    1320   var div = elt('div'); 
     1231  var div = elt('div') 
    13211232  return "draggable" in div || "dragDrop" in div 
    1322 }(); 
    1323  
    1324 var zwspSupported; 
     1233}() 
     1234 
     1235var zwspSupported 
    13251236function zeroWidthElement(measure) { 
    13261237  if (zwspSupported == null) { 
    1327     var test = elt("span", "\u200b"); 
    1328     removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); 
     1238    var test = elt("span", "\u200b") 
     1239    removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])) 
    13291240    if (measure.firstChild.offsetHeight != 0) 
    1330       { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); } 
     1241      { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8) } 
    13311242  } 
    13321243  var node = zwspSupported ? elt("span", "\u200b") : 
    1333     elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); 
    1334   node.setAttribute("cm-text", ""); 
     1244    elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px") 
     1245  node.setAttribute("cm-text", "") 
    13351246  return node 
    13361247} 
    13371248 
    13381249// Feature-detect IE's crummy client rect reporting for bidi text 
    1339 var badBidiRects; 
     1250var badBidiRects 
    13401251function hasBadBidiRects(measure) { 
    13411252  if (badBidiRects != null) { return badBidiRects } 
    1342   var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); 
    1343   var r0 = range(txt, 0, 1).getBoundingClientRect(); 
    1344   var r1 = range(txt, 1, 2).getBoundingClientRect(); 
    1345   removeChildren(measure); 
     1253  var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")) 
     1254  var r0 = range(txt, 0, 1).getBoundingClientRect() 
     1255  var r1 = range(txt, 1, 2).getBoundingClientRect() 
     1256  removeChildren(measure) 
    13461257  if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780) 
    13471258  return badBidiRects = (r1.right - r0.right < 3) 
     
    13511262// alternative way to split lines. 
    13521263var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) { 
    1353   var pos = 0, result = [], l = string.length; 
     1264  var pos = 0, result = [], l = string.length 
    13541265  while (pos <= l) { 
    1355     var nl = string.indexOf("\n", pos); 
    1356     if (nl == -1) { nl = string.length; } 
    1357     var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); 
    1358     var rt = line.indexOf("\r"); 
     1266    var nl = string.indexOf("\n", pos) 
     1267    if (nl == -1) { nl = string.length } 
     1268    var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl) 
     1269    var rt = line.indexOf("\r") 
    13591270    if (rt != -1) { 
    1360       result.push(line.slice(0, rt)); 
    1361       pos += rt + 1; 
     1271      result.push(line.slice(0, rt)) 
     1272      pos += rt + 1 
    13621273    } else { 
    1363       result.push(line); 
    1364       pos = nl + 1; 
     1274      result.push(line) 
     1275      pos = nl + 1 
    13651276    } 
    13661277  } 
    13671278  return result 
    1368 } : function (string) { return string.split(/\r\n?|\n/); }; 
     1279} : function (string) { return string.split(/\r\n?|\n/); } 
    13691280 
    13701281var hasSelection = window.getSelection ? function (te) { 
     
    13721283  catch(e) { return false } 
    13731284} : function (te) { 
    1374   var range$$1; 
    1375   try {range$$1 = te.ownerDocument.selection.createRange();} 
     1285  var range 
     1286  try {range = te.ownerDocument.selection.createRange()} 
    13761287  catch(e) {} 
    1377   if (!range$$1 || range$$1.parentElement() != te) { return false } 
    1378   return range$$1.compareEndPoints("StartToEnd", range$$1) != 0 
    1379 }; 
     1288  if (!range || range.parentElement() != te) { return false } 
     1289  return range.compareEndPoints("StartToEnd", range) != 0 
     1290} 
    13801291 
    13811292var hasCopyEvent = (function () { 
    1382   var e = elt("div"); 
     1293  var e = elt("div") 
    13831294  if ("oncopy" in e) { return true } 
    1384   e.setAttribute("oncopy", "return;"); 
     1295  e.setAttribute("oncopy", "return;") 
    13851296  return typeof e.oncopy == "function" 
    1386 })(); 
    1387  
    1388 var badZoomedRects = null; 
     1297})() 
     1298 
     1299var badZoomedRects = null 
    13891300function hasBadZoomedRects(measure) { 
    13901301  if (badZoomedRects != null) { return badZoomedRects } 
    1391   var node = removeChildrenAndAdd(measure, elt("span", "x")); 
    1392   var normal = node.getBoundingClientRect(); 
    1393   var fromRange = range(node, 0, 1).getBoundingClientRect(); 
     1302  var node = removeChildrenAndAdd(measure, elt("span", "x")) 
     1303  var normal = node.getBoundingClientRect() 
     1304  var fromRange = range(node, 0, 1).getBoundingClientRect() 
    13941305  return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1 
    13951306} 
    13961307 
    1397 // Known modes, by name and by MIME 
    13981308var modes = {}; 
    13991309var mimeModes = {}; 
    1400  
    14011310// Extra arguments are stored as the mode's dependencies, which is 
    14021311// used by (legacy) mechanisms like loadmode.js to automatically 
     
    14041313function defineMode(name, mode) { 
    14051314  if (arguments.length > 2) 
    1406     { mode.dependencies = Array.prototype.slice.call(arguments, 2); } 
    1407   modes[name] = mode; 
     1315    { mode.dependencies = Array.prototype.slice.call(arguments, 2) } 
     1316  modes[name] = mode 
    14081317} 
    14091318 
    14101319function defineMIME(mime, spec) { 
    1411   mimeModes[mime] = spec; 
     1320  mimeModes[mime] = spec 
    14121321} 
    14131322 
     
    14161325function resolveMode(spec) { 
    14171326  if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { 
    1418     spec = mimeModes[spec]; 
     1327    spec = mimeModes[spec] 
    14191328  } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { 
    1420     var found = mimeModes[spec.name]; 
    1421     if (typeof found == "string") { found = {name: found}; } 
    1422     spec = createObj(found, spec); 
    1423     spec.name = found.name; 
     1329    var found = mimeModes[spec.name] 
     1330    if (typeof found == "string") { found = {name: found} } 
     1331    spec = createObj(found, spec) 
     1332    spec.name = found.name 
    14241333  } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { 
    14251334    return resolveMode("application/xml") 
     
    14341343// initialize an actual mode object. 
    14351344function getMode(options, spec) { 
    1436   spec = resolveMode(spec); 
    1437   var mfactory = modes[spec.name]; 
     1345  spec = resolveMode(spec) 
     1346  var mfactory = modes[spec.name] 
    14381347  if (!mfactory) { return getMode(options, "text/plain") } 
    1439   var modeObj = mfactory(options, spec); 
     1348  var modeObj = mfactory(options, spec) 
    14401349  if (modeExtensions.hasOwnProperty(spec.name)) { 
    1441     var exts = modeExtensions[spec.name]; 
     1350    var exts = modeExtensions[spec.name] 
    14421351    for (var prop in exts) { 
    14431352      if (!exts.hasOwnProperty(prop)) { continue } 
    1444       if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; } 
    1445       modeObj[prop] = exts[prop]; 
    1446     } 
    1447   } 
    1448   modeObj.name = spec.name; 
    1449   if (spec.helperType) { modeObj.helperType = spec.helperType; } 
     1353      if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop] } 
     1354      modeObj[prop] = exts[prop] 
     1355    } 
     1356  } 
     1357  modeObj.name = spec.name 
     1358  if (spec.helperType) { modeObj.helperType = spec.helperType } 
    14501359  if (spec.modeProps) { for (var prop$1 in spec.modeProps) 
    1451     { modeObj[prop$1] = spec.modeProps[prop$1]; } } 
     1360    { modeObj[prop$1] = spec.modeProps[prop$1] } } 
    14521361 
    14531362  return modeObj 
     
    14561365// This can be used to attach properties to mode objects from 
    14571366// outside the actual mode definition. 
    1458 var modeExtensions = {}; 
     1367var modeExtensions = {} 
    14591368function extendMode(mode, properties) { 
    1460   var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); 
    1461   copyObj(properties, exts); 
     1369  var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}) 
     1370  copyObj(properties, exts) 
    14621371} 
    14631372 
     
    14651374  if (state === true) { return state } 
    14661375  if (mode.copyState) { return mode.copyState(state) } 
    1467   var nstate = {}; 
     1376  var nstate = {} 
    14681377  for (var n in state) { 
    1469     var val = state[n]; 
    1470     if (val instanceof Array) { val = val.concat([]); } 
    1471     nstate[n] = val; 
     1378    var val = state[n] 
     1379    if (val instanceof Array) { val = val.concat([]) } 
     1380    nstate[n] = val 
    14721381  } 
    14731382  return nstate 
     
    14771386// state at the position that the state refers to. 
    14781387function innerMode(mode, state) { 
    1479   var info; 
     1388  var info 
    14801389  while (mode.innerMode) { 
    1481     info = mode.innerMode(state); 
     1390    info = mode.innerMode(state) 
    14821391    if (!info || info.mode == mode) { break } 
    1483     state = info.state; 
    1484     mode = info.mode; 
     1392    state = info.state 
     1393    mode = info.mode 
    14851394  } 
    14861395  return info || {mode: mode, state: state} 
     
    14961405// parsers more succinct. 
    14971406 
    1498 var StringStream = function(string, tabSize) { 
    1499   this.pos = this.start = 0; 
    1500   this.string = string; 
    1501   this.tabSize = tabSize || 8; 
    1502   this.lastColumnPos = this.lastColumnValue = 0; 
    1503   this.lineStart = 0; 
     1407var StringStream = function(string, tabSize, lineOracle) { 
     1408  this.pos = this.start = 0 
     1409  this.string = string 
     1410  this.tabSize = tabSize || 8 
     1411  this.lastColumnPos = this.lastColumnValue = 0 
     1412  this.lineStart = 0 
     1413  this.lineOracle = lineOracle 
    15041414}; 
    15051415 
     
    15121422}; 
    15131423StringStream.prototype.eat = function (match) { 
    1514   var ch = this.string.charAt(this.pos); 
    1515   var ok; 
    1516   if (typeof match == "string") { ok = ch == match; } 
    1517   else { ok = ch && (match.test ? match.test(ch) : match(ch)); } 
     1424  var ch = this.string.charAt(this.pos) 
     1425  var ok 
     1426  if (typeof match == "string") { ok = ch == match } 
     1427  else { ok = ch && (match.test ? match.test(ch) : match(ch)) } 
    15181428  if (ok) {++this.pos; return ch} 
    15191429}; 
    15201430StringStream.prototype.eatWhile = function (match) { 
    1521   var start = this.pos; 
     1431  var start = this.pos 
    15221432  while (this.eat(match)){} 
    15231433  return this.pos > start 
     
    15261436    var this$1 = this; 
    15271437 
    1528   var start = this.pos; 
    1529   while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos; } 
     1438  var start = this.pos 
     1439  while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos } 
    15301440  return this.pos > start 
    15311441}; 
    1532 StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;}; 
     1442StringStream.prototype.skipToEnd = function () {this.pos = this.string.length}; 
    15331443StringStream.prototype.skipTo = function (ch) { 
    1534   var found = this.string.indexOf(ch, this.pos); 
     1444  var found = this.string.indexOf(ch, this.pos) 
    15351445  if (found > -1) {this.pos = found; return true} 
    15361446}; 
    1537 StringStream.prototype.backUp = function (n) {this.pos -= n;}; 
     1447StringStream.prototype.backUp = function (n) {this.pos -= n}; 
    15381448StringStream.prototype.column = function () { 
    15391449  if (this.lastColumnPos < this.start) { 
    1540     this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); 
    1541     this.lastColumnPos = this.start; 
     1450    this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue) 
     1451    this.lastColumnPos = this.start 
    15421452  } 
    15431453  return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) 
     
    15491459StringStream.prototype.match = function (pattern, consume, caseInsensitive) { 
    15501460  if (typeof pattern == "string") { 
    1551     var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; 
    1552     var substr = this.string.substr(this.pos, pattern.length); 
     1461    var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; } 
     1462    var substr = this.string.substr(this.pos, pattern.length) 
    15531463    if (cased(substr) == cased(pattern)) { 
    1554       if (consume !== false) { this.pos += pattern.length; } 
     1464      if (consume !== false) { this.pos += pattern.length } 
    15551465      return true 
    15561466    } 
    15571467  } else { 
    1558     var match = this.string.slice(this.pos).match(pattern); 
     1468    var match = this.string.slice(this.pos).match(pattern) 
    15591469    if (match && match.index > 0) { return null } 
    1560     if (match && consume !== false) { this.pos += match[0].length; } 
     1470    if (match && consume !== false) { this.pos += match[0].length } 
    15611471    return match 
    15621472  } 
     
    15641474StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)}; 
    15651475StringStream.prototype.hideFirstChars = function (n, inner) { 
    1566   this.lineStart += n; 
     1476  this.lineStart += n 
    15671477  try { return inner() } 
    1568   finally { this.lineStart -= n; } 
     1478  finally { this.lineStart -= n } 
    15691479}; 
     1480StringStream.prototype.lookAhead = function (n) { 
     1481  var oracle = this.lineOracle 
     1482  return oracle && oracle.lookAhead(n) 
     1483}; 
     1484StringStream.prototype.baseToken = function () { 
     1485  var oracle = this.lineOracle 
     1486  return oracle && oracle.baseToken(this.pos) 
     1487}; 
     1488 
     1489var SavedContext = function(state, lookAhead) { 
     1490  this.state = state 
     1491  this.lookAhead = lookAhead 
     1492}; 
     1493 
     1494var Context = function(doc, state, line, lookAhead) { 
     1495  this.state = state 
     1496  this.doc = doc 
     1497  this.line = line 
     1498  this.maxLookAhead = lookAhead || 0 
     1499  this.baseTokens = null 
     1500  this.baseTokenPos = 1 
     1501}; 
     1502 
     1503Context.prototype.lookAhead = function (n) { 
     1504  var line = this.doc.getLine(this.line + n) 
     1505  if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n } 
     1506  return line 
     1507}; 
     1508 
     1509Context.prototype.baseToken = function (n) { 
     1510    var this$1 = this; 
     1511 
     1512  if (!this.baseTokens) { return null } 
     1513  while (this.baseTokens[this.baseTokenPos] <= n) 
     1514    { this$1.baseTokenPos += 2 } 
     1515  var type = this.baseTokens[this.baseTokenPos + 1] 
     1516  return {type: type && type.replace(/( |^)overlay .*/, ""), 
     1517          size: this.baseTokens[this.baseTokenPos] - n} 
     1518}; 
     1519 
     1520Context.prototype.nextLine = function () { 
     1521  this.line++ 
     1522  if (this.maxLookAhead > 0) { this.maxLookAhead-- } 
     1523}; 
     1524 
     1525Context.fromSaved = function (doc, saved, line) { 
     1526  if (saved instanceof SavedContext) 
     1527    { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) } 
     1528  else 
     1529    { return new Context(doc, copyState(doc.mode, saved), line) } 
     1530}; 
     1531 
     1532Context.prototype.save = function (copy) { 
     1533  var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state 
     1534  return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state 
     1535}; 
     1536 
    15701537 
    15711538// Compute a style array (an array starting with a mode generation 
     
    15731540// style strings), which is used to highlight the tokens on the 
    15741541// line. 
    1575 function highlightLine(cm, line, state, forceToEnd) { 
     1542function highlightLine(cm, line, context, forceToEnd) { 
    15761543  // A styles array always starts with a number identifying the 
    15771544  // mode/overlays that it is based on (for easy invalidation). 
    1578   var st = [cm.state.modeGen], lineClasses = {}; 
     1545  var st = [cm.state.modeGen], lineClasses = {} 
    15791546  // Compute the base array of styles 
    1580   runMode(cm, line.text, cm.doc.mode, state, function (end, style) { return st.push(end, style); }, 
    1581     lineClasses, forceToEnd); 
     1547  runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); }, 
     1548          lineClasses, forceToEnd) 
     1549  var state = context.state 
    15821550 
    15831551  // Run overlays, adjust style array. 
    15841552  var loop = function ( o ) { 
    1585     var overlay = cm.state.overlays[o], i = 1, at = 0; 
    1586     runMode(cm, line.text, overlay.mode, true, function (end, style) { 
    1587       var start = i; 
     1553    context.baseTokens = st 
     1554    var overlay = cm.state.overlays[o], i = 1, at = 0 
     1555    context.state = true 
     1556    runMode(cm, line.text, overlay.mode, context, function (end, style) { 
     1557      var start = i 
    15881558      // Ensure there's a token end at the current position, and that i points at it 
    15891559      while (at < end) { 
    1590         var i_end = st[i]; 
     1560        var i_end = st[i] 
    15911561        if (i_end > end) 
    1592           { st.splice(i, 1, end, st[i+1], i_end); } 
    1593         i += 2; 
    1594         at = Math.min(end, i_end); 
     1562          { st.splice(i, 1, end, st[i+1], i_end) } 
     1563        i += 2 
     1564        at = Math.min(end, i_end) 
    15951565      } 
    15961566      if (!style) { return } 
    15971567      if (overlay.opaque) { 
    1598         st.splice(start, i - start, end, "overlay " + style); 
    1599         i = start + 2; 
     1568        st.splice(start, i - start, end, "overlay " + style) 
     1569        i = start + 2 
    16001570      } else { 
    16011571        for (; start < i; start += 2) { 
    1602           var cur = st[start+1]; 
    1603           st[start+1] = (cur ? cur + " " : "") + "overlay " + style; 
     1572          var cur = st[start+1] 
     1573          st[start+1] = (cur ? cur + " " : "") + "overlay " + style 
    16041574        } 
    16051575      } 
    1606     }, lineClasses); 
     1576    }, lineClasses) 
     1577    context.state = state 
     1578    context.baseTokens = null 
     1579    context.baseTokenPos = 1 
    16071580  }; 
    16081581 
     
    16141587function getLineStyles(cm, line, updateFrontier) { 
    16151588  if (!line.styles || line.styles[0] != cm.state.modeGen) { 
    1616     var state = getStateBefore(cm, lineNo(line)); 
    1617     var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state); 
    1618     line.stateAfter = state; 
    1619     line.styles = result.styles; 
    1620     if (result.classes) { line.styleClasses = result.classes; } 
    1621     else if (line.styleClasses) { line.styleClasses = null; } 
    1622     if (updateFrontier === cm.doc.frontier) { cm.doc.frontier++; } 
     1589    var context = getContextBefore(cm, lineNo(line)) 
     1590    var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state) 
     1591    var result = highlightLine(cm, line, context) 
     1592    if (resetState) { context.state = resetState } 
     1593    line.stateAfter = context.save(!resetState) 
     1594    line.styles = result.styles 
     1595    if (result.classes) { line.styleClasses = result.classes } 
     1596    else if (line.styleClasses) { line.styleClasses = null } 
     1597    if (updateFrontier === cm.doc.highlightFrontier) 
     1598      { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier) } 
    16231599  } 
    16241600  return line.styles 
    16251601} 
    16261602 
    1627 function getStateBefore(cm, n, precise) { 
    1628   var doc = cm.doc, display = cm.display; 
    1629   if (!doc.mode.startState) { return true } 
    1630   var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; 
    1631   if (!state) { state = startState(doc.mode); } 
    1632   else { state = copyState(doc.mode, state); } 
    1633   doc.iter(pos, n, function (line) { 
    1634     processLine(cm, line.text, state); 
    1635     var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; 
    1636     line.stateAfter = save ? copyState(doc.mode, state) : null; 
    1637     ++pos; 
    1638   }); 
    1639   if (precise) { doc.frontier = pos; } 
    1640   return state 
     1603function getContextBefore(cm, n, precise) { 
     1604  var doc = cm.doc, display = cm.display 
     1605  if (!doc.mode.startState) { return new Context(doc, true, n) } 
     1606  var start = findStartLine(cm, n, precise) 
     1607  var saved = start > doc.first && getLine(doc, start - 1).stateAfter 
     1608  var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start) 
     1609 
     1610  doc.iter(start, n, function (line) { 
     1611    processLine(cm, line.text, context) 
     1612    var pos = context.line 
     1613    line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null 
     1614    context.nextLine() 
     1615  }) 
     1616  if (precise) { doc.modeFrontier = context.line } 
     1617  return context 
    16411618} 
    16421619 
     
    16441621// update state, but don't save a style array. Used for lines that 
    16451622// aren't currently visible. 
    1646 function processLine(cm, text, state, startAt) { 
    1647   var mode = cm.doc.mode; 
    1648   var stream = new StringStream(text, cm.options.tabSize); 
    1649   stream.start = stream.pos = startAt || 0; 
    1650   if (text == "") { callBlankLine(mode, state); } 
     1623function processLine(cm, text, context, startAt) { 
     1624  var mode = cm.doc.mode 
     1625  var stream = new StringStream(text, cm.options.tabSize, context) 
     1626  stream.start = stream.pos = startAt || 0 
     1627  if (text == "") { callBlankLine(mode, context.state) } 
    16511628  while (!stream.eol()) { 
    1652     readToken(mode, stream, state); 
    1653     stream.start = stream.pos; 
     1629    readToken(mode, stream, context.state) 
     1630    stream.start = stream.pos 
    16541631  } 
    16551632} 
     
    16581635  if (mode.blankLine) { return mode.blankLine(state) } 
    16591636  if (!mode.innerMode) { return } 
    1660   var inner = innerMode(mode, state); 
     1637  var inner = innerMode(mode, state) 
    16611638  if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) } 
    16621639} 
     
    16641641function readToken(mode, stream, state, inner) { 
    16651642  for (var i = 0; i < 10; i++) { 
    1666     if (inner) { inner[0] = innerMode(mode, state).mode; } 
    1667     var style = mode.token(stream, state); 
     1643    if (inner) { inner[0] = innerMode(mode, state).mode } 
     1644    var style = mode.token(stream, state) 
    16681645    if (stream.pos > stream.start) { return style } 
    16691646  } 
    16701647  throw new Error("Mode " + mode.name + " failed to advance stream.") 
    16711648} 
     1649 
     1650var Token = function(stream, type, state) { 
     1651  this.start = stream.start; this.end = stream.pos 
     1652  this.string = stream.current() 
     1653  this.type = type || null 
     1654  this.state = state 
     1655}; 
    16721656 
    16731657// Utility for getTokenAt and getLineTokens 
    16741658function takeToken(cm, pos, precise, asArray) { 
    1675   var getObj = function (copy) { return ({ 
    1676     start: stream.start, end: stream.pos, 
    1677     string: stream.current(), 
    1678     type: style || null, 
    1679     state: copy ? copyState(doc.mode, state) : state 
    1680   }); }; 
    1681  
    1682   var doc = cm.doc, mode = doc.mode, style; 
    1683   pos = clipPos(doc, pos); 
    1684   var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); 
    1685   var stream = new StringStream(line.text, cm.options.tabSize), tokens; 
    1686   if (asArray) { tokens = []; } 
     1659  var doc = cm.doc, mode = doc.mode, style 
     1660  pos = clipPos(doc, pos) 
     1661  var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise) 
     1662  var stream = new StringStream(line.text, cm.options.tabSize, context), tokens 
     1663  if (asArray) { tokens = [] } 
    16871664  while ((asArray || stream.pos < pos.ch) && !stream.eol()) { 
    1688     stream.start = stream.pos; 
    1689     style = readToken(mode, stream, state); 
    1690     if (asArray) { tokens.push(getObj(true)); } 
    1691   } 
    1692   return asArray ? tokens : getObj() 
     1665    stream.start = stream.pos 
     1666    style = readToken(mode, stream, context.state) 
     1667    if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))) } 
     1668  } 
     1669  return asArray ? tokens : new Token(stream, style, context.state) 
    16931670} 
    16941671 
    16951672function extractLineClasses(type, output) { 
    16961673  if (type) { for (;;) { 
    1697     var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); 
     1674    var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/) 
    16981675    if (!lineClass) { break } 
    1699     type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); 
    1700     var prop = lineClass[1] ? "bgClass" : "textClass"; 
     1676    type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length) 
     1677    var prop = lineClass[1] ? "bgClass" : "textClass" 
    17011678    if (output[prop] == null) 
    1702       { output[prop] = lineClass[2]; } 
     1679      { output[prop] = lineClass[2] } 
    17031680    else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) 
    1704       { output[prop] += " " + lineClass[2]; } 
     1681      { output[prop] += " " + lineClass[2] } 
    17051682  } } 
    17061683  return type 
     
    17081685 
    17091686// Run the given mode's parser over a line, calling f for each token. 
    1710 function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { 
    1711   var flattenSpans = mode.flattenSpans; 
    1712   if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; } 
    1713   var curStart = 0, curStyle = null; 
    1714   var stream = new StringStream(text, cm.options.tabSize), style; 
    1715   var inner = cm.options.addModeClass && [null]; 
    1716   if (text == "") { extractLineClasses(callBlankLine(mode, state), lineClasses); } 
     1687function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) { 
     1688  var flattenSpans = mode.flattenSpans 
     1689  if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans } 
     1690  var curStart = 0, curStyle = null 
     1691  var stream = new StringStream(text, cm.options.tabSize, context), style 
     1692  var inner = cm.options.addModeClass && [null] 
     1693  if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses) } 
    17171694  while (!stream.eol()) { 
    17181695    if (stream.pos > cm.options.maxHighlightLength) { 
    1719       flattenSpans = false; 
    1720       if (forceToEnd) { processLine(cm, text, state, stream.pos); } 
    1721       stream.pos = text.length; 
    1722       style = null; 
     1696      flattenSpans = false 
     1697      if (forceToEnd) { processLine(cm, text, context, stream.pos) } 
     1698      stream.pos = text.length 
     1699      style = null 
    17231700    } else { 
    1724       style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); 
     1701      style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses) 
    17251702    } 
    17261703    if (inner) { 
    1727       var mName = inner[0].name; 
    1728       if (mName) { style = "m-" + (style ? mName + " " + style : mName); } 
     1704      var mName = inner[0].name 
     1705      if (mName) { style = "m-" + (style ? mName + " " + style : mName) } 
    17291706    } 
    17301707    if (!flattenSpans || curStyle != style) { 
    17311708      while (curStart < stream.start) { 
    1732         curStart = Math.min(stream.start, curStart + 5000); 
    1733         f(curStart, curStyle); 
     1709        curStart = Math.min(stream.start, curStart + 5000) 
     1710        f(curStart, curStyle) 
    17341711      } 
    1735       curStyle = style; 
    1736     } 
    1737     stream.start = stream.pos; 
     1712      curStyle = style 
     1713    } 
     1714    stream.start = stream.pos 
    17381715  } 
    17391716  while (curStart < stream.pos) { 
     
    17411718    // characters, and returns inaccurate measurements in nodes 
    17421719    // starting around 5000 chars. 
    1743     var pos = Math.min(stream.pos, curStart + 5000); 
    1744     f(pos, curStyle); 
    1745     curStart = pos; 
     1720    var pos = Math.min(stream.pos, curStart + 5000) 
     1721    f(pos, curStyle) 
     1722    curStart = pos 
    17461723  } 
    17471724} 
     
    17531730// parse correctly. 
    17541731function findStartLine(cm, n, precise) { 
    1755   var minindent, minline, doc = cm.doc; 
    1756   var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); 
     1732  var minindent, minline, doc = cm.doc 
     1733  var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100) 
    17571734  for (var search = n; search > lim; --search) { 
    17581735    if (search <= doc.first) { return doc.first } 
    1759     var line = getLine(doc, search - 1); 
    1760     if (line.stateAfter && (!precise || search <= doc.frontier)) { return search } 
    1761     var indented = countColumn(line.text, null, cm.options.tabSize); 
     1736    var line = getLine(doc, search - 1), after = line.stateAfter 
     1737    if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier)) 
     1738      { return search } 
     1739    var indented = countColumn(line.text, null, cm.options.tabSize) 
    17621740    if (minline == null || minindent > indented) { 
    1763       minline = search - 1; 
    1764       minindent = indented; 
     1741      minline = search - 1 
     1742      minindent = indented 
    17651743    } 
    17661744  } 
    17671745  return minline 
     1746} 
     1747 
     1748function retreatFrontier(doc, n) { 
     1749  doc.modeFrontier = Math.min(doc.modeFrontier, n) 
     1750  if (doc.highlightFrontier < n - 10) { return } 
     1751  var start = doc.first 
     1752  for (var line = n - 1; line > start; line--) { 
     1753    var saved = getLine(doc, line).stateAfter 
     1754    // change is on 3 
     1755    // state on line 1 looked ahead 2 -- so saw 3 
     1756    // test 1 + 2 < 3 should cover this 
     1757    if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) { 
     1758      start = line + 1 
     1759      break 
     1760    } 
     1761  } 
     1762  doc.highlightFrontier = Math.min(doc.highlightFrontier, start) 
    17681763} 
    17691764 
     
    17731768// highlighting info (the styles array). 
    17741769var Line = function(text, markedSpans, estimateHeight) { 
    1775   this.text = text; 
    1776   attachMarkedSpans(this, markedSpans); 
    1777   this.height = estimateHeight ? estimateHeight(this) : 1; 
     1770  this.text = text 
     1771  attachMarkedSpans(this, markedSpans) 
     1772  this.height = estimateHeight ? estimateHeight(this) : 1 
    17781773}; 
    17791774 
    17801775Line.prototype.lineNo = function () { return lineNo(this) }; 
    1781 eventMixin(Line); 
     1776eventMixin(Line) 
    17821777 
    17831778// Change the content (text, markers) of a line. Automatically 
     
    17851780// line's height. 
    17861781function updateLine(line, text, markedSpans, estimateHeight) { 
    1787   line.text = text; 
    1788   if (line.stateAfter) { line.stateAfter = null; } 
    1789   if (line.styles) { line.styles = null; } 
    1790   if (line.order != null) { line.order = null; } 
    1791   detachMarkedSpans(line); 
    1792   attachMarkedSpans(line, markedSpans); 
    1793   var estHeight = estimateHeight ? estimateHeight(line) : 1; 
    1794   if (estHeight != line.height) { updateLineHeight(line, estHeight); } 
     1782  line.text = text 
     1783  if (line.stateAfter) { line.stateAfter = null } 
     1784  if (line.styles) { line.styles = null } 
     1785  if (line.order != null) { line.order = null } 
     1786  detachMarkedSpans(line) 
     1787  attachMarkedSpans(line, markedSpans) 
     1788  var estHeight = estimateHeight ? estimateHeight(line) : 1 
     1789  if (estHeight != line.height) { updateLineHeight(line, estHeight) } 
    17951790} 
    17961791 
    17971792// Detach a line from the document tree and its markers. 
    17981793function cleanUpLine(line) { 
    1799   line.parent = null; 
    1800   detachMarkedSpans(line); 
     1794  line.parent = null 
     1795  detachMarkedSpans(line) 
    18011796} 
    18021797 
     
    18081803function interpretTokenStyle(style, options) { 
    18091804  if (!style || /^\s*$/.test(style)) { return null } 
    1810   var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; 
     1805  var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache 
    18111806  return cache[style] || 
    18121807    (cache[style] = style.replace(/\S+/g, "cm-$&")) 
     
    18221817  // is needed on Webkit to be able to get line-level bounding 
    18231818  // rectangles for it (in measureChar). 
    1824   var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null); 
     1819  var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null) 
    18251820  var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content, 
    18261821                 col: 0, pos: 0, cm: cm, 
    18271822                 trailingSpace: false, 
    1828                  splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}; 
    1829   lineView.measure = {}; 
     1823                 splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")} 
     1824  lineView.measure = {} 
    18301825 
    18311826  // Iterate over the logical lines that make up this visual line. 
    18321827  for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { 
    1833     var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0); 
    1834     builder.pos = 0; 
    1835     builder.addToken = buildToken; 
     1828    var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0) 
     1829    builder.pos = 0 
     1830    builder.addToken = buildToken 
    18361831    // Optionally wire in some hacks into the token-rendering 
    18371832    // algorithm, to deal with browser quirks. 
    18381833    if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction))) 
    1839       { builder.addToken = buildTokenBadBidi(builder.addToken, order); } 
    1840     builder.map = []; 
    1841     var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); 
    1842     insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); 
     1834      { builder.addToken = buildTokenBadBidi(builder.addToken, order) } 
     1835    builder.map = [] 
     1836    var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line) 
     1837    insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)) 
    18431838    if (line.styleClasses) { 
    18441839      if (line.styleClasses.bgClass) 
    1845         { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); } 
     1840        { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "") } 
    18461841      if (line.styleClasses.textClass) 
    1847         { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); } 
     1842        { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "") } 
    18481843    } 
    18491844 
    18501845    // Ensure at least a single node is present, for measuring. 
    18511846    if (builder.map.length == 0) 
    1852       { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); } 
     1847      { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))) } 
    18531848 
    18541849    // Store the map and a cache object for the current logical line 
    18551850    if (i == 0) { 
    1856       lineView.measure.map = builder.map; 
    1857       lineView.measure.cache = {}; 
     1851      lineView.measure.map = builder.map 
     1852      lineView.measure.cache = {} 
    18581853    } else { 
    1859       (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map) 
    1860       ;(lineView.measure.caches || (lineView.measure.caches = [])).push({}); 
     1854      ;(lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map) 
     1855      ;(lineView.measure.caches || (lineView.measure.caches = [])).push({}) 
    18611856    } 
    18621857  } 
     
    18641859  // See issue #2901 
    18651860  if (webkit) { 
    1866     var last = builder.content.lastChild; 
     1861    var last = builder.content.lastChild 
    18671862    if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) 
    1868       { builder.content.className = "cm-tab-wrap-hack"; } 
    1869   } 
    1870  
    1871   signal(cm, "renderLine", cm, lineView.line, builder.pre); 
     1863      { builder.content.className = "cm-tab-wrap-hack" } 
     1864  } 
     1865 
     1866  signal(cm, "renderLine", cm, lineView.line, builder.pre) 
    18721867  if (builder.pre.className) 
    1873     { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); } 
     1868    { builder.textClass = joinClasses(builder.pre.className, builder.textClass || "") } 
    18741869 
    18751870  return builder 
     
    18771872 
    18781873function defaultSpecialCharPlaceholder(ch) { 
    1879   var token = elt("span", "\u2022", "cm-invalidchar"); 
    1880   token.title = "\\u" + ch.charCodeAt(0).toString(16); 
    1881   token.setAttribute("aria-label", token.title); 
     1874  var token = elt("span", "\u2022", "cm-invalidchar") 
     1875  token.title = "\\u" + ch.charCodeAt(0).toString(16) 
     1876  token.setAttribute("aria-label", token.title) 
    18821877  return token 
    18831878} 
     
    18871882function buildToken(builder, text, style, startStyle, endStyle, title, css) { 
    18881883  if (!text) { return } 
    1889   var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text; 
    1890   var special = builder.cm.state.specialChars, mustWrap = false; 
    1891   var content; 
     1884  var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text 
     1885  var special = builder.cm.state.specialChars, mustWrap = false 
     1886  var content 
    18921887  if (!special.test(text)) { 
    1893     builder.col += text.length; 
    1894     content = document.createTextNode(displayText); 
    1895     builder.map.push(builder.pos, builder.pos + text.length, content); 
    1896     if (ie && ie_version < 9) { mustWrap = true; } 
    1897     builder.pos += text.length; 
     1888    builder.col += text.length 
     1889    content = document.createTextNode(displayText) 
     1890    builder.map.push(builder.pos, builder.pos + text.length, content) 
     1891    if (ie && ie_version < 9) { mustWrap = true } 
     1892    builder.pos += text.length 
    18981893  } else { 
    1899     content = document.createDocumentFragment(); 
    1900     var pos = 0; 
     1894    content = document.createDocumentFragment() 
     1895    var pos = 0 
    19011896    while (true) { 
    1902       special.lastIndex = pos; 
    1903       var m = special.exec(text); 
    1904       var skipped = m ? m.index - pos : text.length - pos; 
     1897      special.lastIndex = pos 
     1898      var m = special.exec(text) 
     1899      var skipped = m ? m.index - pos : text.length - pos 
    19051900      if (skipped) { 
    1906         var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); 
    1907         if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); } 
    1908         else { content.appendChild(txt); } 
    1909         builder.map.push(builder.pos, builder.pos + skipped, txt); 
    1910         builder.col += skipped; 
    1911         builder.pos += skipped; 
     1901        var txt = document.createTextNode(displayText.slice(pos, pos + skipped)) 
     1902        if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])) } 
     1903        else { content.appendChild(txt) } 
     1904        builder.map.push(builder.pos, builder.pos + skipped, txt) 
     1905        builder.col += skipped 
     1906        builder.pos += skipped 
    19121907      } 
    19131908      if (!m) { break } 
    1914       pos += skipped + 1; 
    1915       var txt$1 = (void 0); 
     1909      pos += skipped + 1 
     1910      var txt$1 = (void 0) 
    19161911      if (m[0] == "\t") { 
    1917         var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; 
    1918         txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); 
    1919         txt$1.setAttribute("role", "presentation"); 
    1920         txt$1.setAttribute("cm-text", "\t"); 
    1921         builder.col += tabWidth; 
     1912        var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize 
     1913        txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")) 
     1914        txt$1.setAttribute("role", "presentation") 
     1915        txt$1.setAttribute("cm-text", "\t") 
     1916        builder.col += tabWidth 
    19221917      } else if (m[0] == "\r" || m[0] == "\n") { 
    1923         txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); 
    1924         txt$1.setAttribute("cm-text", m[0]); 
    1925         builder.col += 1; 
     1918        txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")) 
     1919        txt$1.setAttribute("cm-text", m[0]) 
     1920        builder.col += 1 
    19261921      } else { 
    1927         txt$1 = builder.cm.options.specialCharPlaceholder(m[0]); 
    1928         txt$1.setAttribute("cm-text", m[0]); 
    1929         if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); } 
    1930         else { content.appendChild(txt$1); } 
    1931         builder.col += 1; 
     1922        txt$1 = builder.cm.options.specialCharPlaceholder(m[0]) 
     1923        txt$1.setAttribute("cm-text", m[0]) 
     1924        if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])) } 
     1925        else { content.appendChild(txt$1) } 
     1926        builder.col += 1 
    19321927      } 
    1933       builder.map.push(builder.pos, builder.pos + 1, txt$1); 
    1934       builder.pos++; 
    1935     } 
    1936   } 
    1937   builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32; 
     1928      builder.map.push(builder.pos, builder.pos + 1, txt$1) 
     1929      builder.pos++ 
     1930    } 
     1931  } 
     1932  builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32 
    19381933  if (style || startStyle || endStyle || mustWrap || css) { 
    1939     var fullStyle = style || ""; 
    1940     if (startStyle) { fullStyle += startStyle; } 
    1941     if (endStyle) { fullStyle += endStyle; } 
    1942     var token = elt("span", [content], fullStyle, css); 
    1943     if (title) { token.title = title; } 
     1934    var fullStyle = style || "" 
     1935    if (startStyle) { fullStyle += startStyle } 
     1936    if (endStyle) { fullStyle += endStyle } 
     1937    var token = elt("span", [content], fullStyle, css) 
     1938    if (title) { token.title = title } 
    19441939    return builder.content.appendChild(token) 
    19451940  } 
    1946   builder.content.appendChild(content); 
     1941  builder.content.appendChild(content) 
    19471942} 
    19481943 
    19491944function splitSpaces(text, trailingBefore) { 
    19501945  if (text.length > 1 && !/  /.test(text)) { return text } 
    1951   var spaceBefore = trailingBefore, result = ""; 
     1946  var spaceBefore = trailingBefore, result = "" 
    19521947  for (var i = 0; i < text.length; i++) { 
    1953     var ch = text.charAt(i); 
     1948    var ch = text.charAt(i) 
    19541949    if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) 
    1955       { ch = "\u00a0"; } 
    1956     result += ch; 
    1957     spaceBefore = ch == " "; 
     1950      { ch = "\u00a0" } 
     1951    result += ch 
     1952    spaceBefore = ch == " " 
    19581953  } 
    19591954  return result 
     
    19641959function buildTokenBadBidi(inner, order) { 
    19651960  return function (builder, text, style, startStyle, endStyle, title, css) { 
    1966     style = style ? style + " cm-force-border" : "cm-force-border"; 
    1967     var start = builder.pos, end = start + text.length; 
     1961    style = style ? style + " cm-force-border" : "cm-force-border" 
     1962    var start = builder.pos, end = start + text.length 
    19681963    for (;;) { 
    19691964      // Find the part that overlaps with the start of this text 
    1970       var part = (void 0); 
     1965      var part = (void 0) 
    19711966      for (var i = 0; i < order.length; i++) { 
    1972         part = order[i]; 
     1967        part = order[i] 
    19731968        if (part.to > start && part.from <= start) { break } 
    19741969      } 
    19751970      if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) } 
    1976       inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); 
    1977       startStyle = null; 
    1978       text = text.slice(part.to - start); 
    1979       start = part.to; 
     1971      inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css) 
     1972      startStyle = null 
     1973      text = text.slice(part.to - start) 
     1974      start = part.to 
    19801975    } 
    19811976  } 
     
    19831978 
    19841979function buildCollapsedSpan(builder, size, marker, ignoreWidget) { 
    1985   var widget = !ignoreWidget && marker.widgetNode; 
    1986   if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); } 
     1980  var widget = !ignoreWidget && marker.widgetNode 
     1981  if (widget) { builder.map.push(builder.pos, builder.pos + size, widget) } 
    19871982  if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { 
    19881983    if (!widget) 
    1989       { widget = builder.content.appendChild(document.createElement("span")); } 
    1990     widget.setAttribute("cm-marker", marker.id); 
     1984      { widget = builder.content.appendChild(document.createElement("span")) } 
     1985    widget.setAttribute("cm-marker", marker.id) 
    19911986  } 
    19921987  if (widget) { 
    1993     builder.cm.display.input.setUneditable(widget); 
    1994     builder.content.appendChild(widget); 
    1995   } 
    1996   builder.pos += size; 
    1997   builder.trailingSpace = false; 
     1988    builder.cm.display.input.setUneditable(widget) 
     1989    builder.content.appendChild(widget) 
     1990  } 
     1991  builder.pos += size 
     1992  builder.trailingSpace = false 
    19981993} 
    19991994 
     
    20011996// and marked text into account. 
    20021997function insertLineContent(line, builder, styles) { 
    2003   var spans = line.markedSpans, allText = line.text, at = 0; 
     1998  var spans = line.markedSpans, allText = line.text, at = 0 
    20041999  if (!spans) { 
    20052000    for (var i$1 = 1; i$1 < styles.length; i$1+=2) 
    2006       { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)); } 
     2001      { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)) } 
    20072002    return 
    20082003  } 
    20092004 
    2010   var len = allText.length, pos = 0, i = 1, text = "", style, css; 
    2011   var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; 
     2005  var len = allText.length, pos = 0, i = 1, text = "", style, css 
     2006  var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed 
    20122007  for (;;) { 
    20132008    if (nextChange == pos) { // Update current marker set 
    2014       spanStyle = spanEndStyle = spanStartStyle = title = css = ""; 
    2015       collapsed = null; nextChange = Infinity; 
    2016       var foundBookmarks = [], endStyles = (void 0); 
     2009      spanStyle = spanEndStyle = spanStartStyle = title = css = "" 
     2010      collapsed = null; nextChange = Infinity 
     2011      var foundBookmarks = [], endStyles = (void 0) 
    20172012      for (var j = 0; j < spans.length; ++j) { 
    2018         var sp = spans[j], m = sp.marker; 
     2013        var sp = spans[j], m = sp.marker 
    20192014        if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { 
    2020           foundBookmarks.push(m); 
     2015          foundBookmarks.push(m) 
    20212016        } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { 
    20222017          if (sp.to != null && sp.to != pos && nextChange > sp.to) { 
    2023             nextChange = sp.to; 
    2024             spanEndStyle = ""; 
     2018            nextChange = sp.to 
     2019            spanEndStyle = "" 
    20252020          } 
    2026           if (m.className) { spanStyle += " " + m.className; } 
    2027           if (m.css) { css = (css ? css + ";" : "") + m.css; } 
    2028           if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; } 
    2029           if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); } 
    2030           if (m.title && !title) { title = m.title; } 
     2021          if (m.className) { spanStyle += " " + m.className } 
     2022          if (m.css) { css = (css ? css + ";" : "") + m.css } 
     2023          if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle } 
     2024          if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to) } 
     2025          if (m.title && !title) { title = m.title } 
    20312026          if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) 
    2032             { collapsed = sp; } 
     2027            { collapsed = sp } 
    20332028        } else if (sp.from > pos && nextChange > sp.from) { 
    2034           nextChange = sp.from; 
     2029          nextChange = sp.from 
    20352030        } 
    20362031      } 
    20372032      if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2) 
    2038         { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } } 
     2033        { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1] } } } 
    20392034 
    20402035      if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2) 
    2041         { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } } 
     2036        { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]) } } 
    20422037      if (collapsed && (collapsed.from || 0) == pos) { 
    20432038        buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, 
    2044                            collapsed.marker, collapsed.from == null); 
     2039                           collapsed.marker, collapsed.from == null) 
    20452040        if (collapsed.to == null) { return } 
    2046         if (collapsed.to == pos) { collapsed = false; } 
     2041        if (collapsed.to == pos) { collapsed = false } 
    20472042      } 
    20482043    } 
    20492044    if (pos >= len) { break } 
    20502045 
    2051     var upto = Math.min(len, nextChange); 
     2046    var upto = Math.min(len, nextChange) 
    20522047    while (true) { 
    20532048      if (text) { 
    2054         var end = pos + text.length; 
     2049        var end = pos + text.length 
    20552050        if (!collapsed) { 
    2056           var tokenText = end > upto ? text.slice(0, upto - pos) : text; 
     2051          var tokenText = end > upto ? text.slice(0, upto - pos) : text 
    20572052          builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, 
    2058                            spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); 
     2053                           spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css) 
    20592054        } 
    20602055        if (end >= upto) {text = text.slice(upto - pos); pos = upto; break} 
    2061         pos = end; 
    2062         spanStartStyle = ""; 
     2056        pos = end 
     2057        spanStartStyle = "" 
    20632058      } 
    2064       text = allText.slice(at, at = styles[i++]); 
    2065       style = interpretTokenStyle(styles[i++], builder.cm.options); 
     2059      text = allText.slice(at, at = styles[i++]) 
     2060      style = interpretTokenStyle(styles[i++], builder.cm.options) 
    20662061    } 
    20672062  } 
     
    20742069function LineView(doc, line, lineN) { 
    20752070  // The starting line 
    2076   this.line = line; 
     2071  this.line = line 
    20772072  // Continuing lines, if any 
    2078   this.rest = visualLineContinued(line); 
     2073  this.rest = visualLineContinued(line) 
    20792074  // Number of logical lines in this visual line 
    2080   this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; 
    2081   this.node = this.text = null; 
    2082   this.hidden = lineIsHidden(doc, line); 
     2075  this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1 
     2076  this.node = this.text = null 
     2077  this.hidden = lineIsHidden(doc, line) 
    20832078} 
    20842079 
    20852080// Create a range of LineView objects for the given lines. 
    20862081function buildViewArray(cm, from, to) { 
    2087   var array = [], nextPos; 
     2082  var array = [], nextPos 
    20882083  for (var pos = from; pos < to; pos = nextPos) { 
    2089     var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); 
    2090     nextPos = pos + view.size; 
    2091     array.push(view); 
     2084    var view = new LineView(cm.doc, getLine(cm.doc, pos), pos) 
     2085    nextPos = pos + view.size 
     2086    array.push(view) 
    20922087  } 
    20932088  return array 
    20942089} 
    20952090 
    2096 var operationGroup = null; 
     2091var operationGroup = null 
    20972092 
    20982093function pushOperation(op) { 
    20992094  if (operationGroup) { 
    2100     operationGroup.ops.push(op); 
     2095    operationGroup.ops.push(op) 
    21012096  } else { 
    21022097    op.ownsGroup = operationGroup = { 
    21032098      ops: [op], 
    21042099      delayedCallbacks: [] 
    2105     }; 
     2100    } 
    21062101  } 
    21072102} 
     
    21102105  // Calls delayed callbacks and cursorActivity handlers until no 
    21112106  // new ones appear 
    2112   var callbacks = group.delayedCallbacks, i = 0; 
     2107  var callbacks = group.delayedCallbacks, i = 0 
    21132108  do { 
    21142109    for (; i < callbacks.length; i++) 
    2115       { callbacks[i].call(null); } 
     2110      { callbacks[i].call(null) } 
    21162111    for (var j = 0; j < group.ops.length; j++) { 
    2117       var op = group.ops[j]; 
     2112      var op = group.ops[j] 
    21182113      if (op.cursorActivityHandlers) 
    21192114        { while (op.cursorActivityCalled < op.cursorActivityHandlers.length) 
    2120           { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } } 
     2115          { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm) } } 
    21212116    } 
    21222117  } while (i < callbacks.length) 
     
    21242119 
    21252120function finishOperation(op, endCb) { 
    2126   var group = op.ownsGroup; 
     2121  var group = op.ownsGroup 
    21272122  if (!group) { return } 
    21282123 
    2129   try { fireCallbacksForOps(group); } 
     2124  try { fireCallbacksForOps(group) } 
    21302125  finally { 
    2131     operationGroup = null; 
    2132     endCb(group); 
    2133   } 
    2134 } 
    2135  
    2136 var orphanDelayedCallbacks = null; 
     2126    operationGroup = null 
     2127    endCb(group) 
     2128  } 
     2129} 
     2130 
     2131var orphanDelayedCallbacks = null 
    21372132 
    21382133// Often, we want to signal events at a point where we are in the 
     
    21442139// operation is active, when a timeout fires. 
    21452140function signalLater(emitter, type /*, values...*/) { 
    2146   var arr = getHandlers(emitter, type); 
     2141  var arr = getHandlers(emitter, type) 
    21472142  if (!arr.length) { return } 
    2148   var args = Array.prototype.slice.call(arguments, 2), list; 
     2143  var args = Array.prototype.slice.call(arguments, 2), list 
    21492144  if (operationGroup) { 
    2150     list = operationGroup.delayedCallbacks; 
     2145    list = operationGroup.delayedCallbacks 
    21512146  } else if (orphanDelayedCallbacks) { 
    2152     list = orphanDelayedCallbacks; 
     2147    list = orphanDelayedCallbacks 
    21532148  } else { 
    2154     list = orphanDelayedCallbacks = []; 
    2155     setTimeout(fireOrphanDelayed, 0); 
     2149    list = orphanDelayedCallbacks = [] 
     2150    setTimeout(fireOrphanDelayed, 0) 
    21562151  } 
    21572152  var loop = function ( i ) { 
    2158     list.push(function () { return arr[i].apply(null, args); }); 
     2153    list.push(function () { return arr[i].apply(null, args); }) 
    21592154  }; 
    21602155 
     
    21642159 
    21652160function fireOrphanDelayed() { 
    2166   var delayed = orphanDelayedCallbacks; 
    2167   orphanDelayedCallbacks = null; 
    2168   for (var i = 0; i < delayed.length; ++i) { delayed[i](); } 
     2161  var delayed = orphanDelayedCallbacks 
     2162  orphanDelayedCallbacks = null 
     2163  for (var i = 0; i < delayed.length; ++i) { delayed[i]() } 
    21692164} 
    21702165 
     
    21742169function updateLineForChanges(cm, lineView, lineN, dims) { 
    21752170  for (var j = 0; j < lineView.changes.length; j++) { 
    2176     var type = lineView.changes[j]; 
    2177     if (type == "text") { updateLineText(cm, lineView); } 
    2178     else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); } 
    2179     else if (type == "class") { updateLineClasses(cm, lineView); } 
    2180     else if (type == "widget") { updateLineWidgets(cm, lineView, dims); } 
    2181   } 
    2182   lineView.changes = null; 
     2171    var type = lineView.changes[j] 
     2172    if (type == "text") { updateLineText(cm, lineView) } 
     2173    else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims) } 
     2174    else if (type == "class") { updateLineClasses(cm, lineView) } 
     2175    else if (type == "widget") { updateLineWidgets(cm, lineView, dims) } 
     2176  } 
     2177  lineView.changes = null 
    21832178} 
    21842179 
     
    21872182function ensureLineWrapped(lineView) { 
    21882183  if (lineView.node == lineView.text) { 
    2189     lineView.node = elt("div", null, null, "position: relative"); 
     2184    lineView.node = elt("div", null, null, "position: relative") 
    21902185    if (lineView.text.parentNode) 
    2191       { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); } 
    2192     lineView.node.appendChild(lineView.text); 
    2193     if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; } 
     2186      { lineView.text.parentNode.replaceChild(lineView.node, lineView.text) } 
     2187    lineView.node.appendChild(lineView.text) 
     2188    if (ie && ie_version < 8) { lineView.node.style.zIndex = 2 } 
    21942189  } 
    21952190  return lineView.node 
     
    21972192 
    21982193function updateLineBackground(cm, lineView) { 
    2199   var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; 
    2200   if (cls) { cls += " CodeMirror-linebackground"; } 
     2194  var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass 
     2195  if (cls) { cls += " CodeMirror-linebackground" } 
    22012196  if (lineView.background) { 
    2202     if (cls) { lineView.background.className = cls; } 
    2203     else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } 
     2197    if (cls) { lineView.background.className = cls } 
     2198    else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null } 
    22042199  } else if (cls) { 
    2205     var wrap = ensureLineWrapped(lineView); 
    2206     lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); 
    2207     cm.display.input.setUneditable(lineView.background); 
     2200    var wrap = ensureLineWrapped(lineView) 
     2201    lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild) 
     2202    cm.display.input.setUneditable(lineView.background) 
    22082203  } 
    22092204} 
     
    22122207// in display.externalMeasured when possible. 
    22132208function getLineContent(cm, lineView) { 
    2214   var ext = cm.display.externalMeasured; 
     2209  var ext = cm.display.externalMeasured 
    22152210  if (ext && ext.line == lineView.line) { 
    2216     cm.display.externalMeasured = null; 
    2217     lineView.measure = ext.measure; 
     2211    cm.display.externalMeasured = null 
     2212    lineView.measure = ext.measure 
    22182213    return ext.built 
    22192214  } 
     
    22252220// classes. 
    22262221function updateLineText(cm, lineView) { 
    2227   var cls = lineView.text.className; 
    2228   var built = getLineContent(cm, lineView); 
    2229   if (lineView.text == lineView.node) { lineView.node = built.pre; } 
    2230   lineView.text.parentNode.replaceChild(built.pre, lineView.text); 
    2231   lineView.text = built.pre; 
     2222  var cls = lineView.text.className 
     2223  var built = getLineContent(cm, lineView) 
     2224  if (lineView.text == lineView.node) { lineView.node = built.pre } 
     2225  lineView.text.parentNode.replaceChild(built.pre, lineView.text) 
     2226  lineView.text = built.pre 
    22322227  if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { 
    2233     lineView.bgClass = built.bgClass; 
    2234     lineView.textClass = built.textClass; 
    2235     updateLineClasses(cm, lineView); 
     2228    lineView.bgClass = built.bgClass 
     2229    lineView.textClass = built.textClass 
     2230    updateLineClasses(cm, lineView) 
    22362231  } else if (cls) { 
    2237     lineView.text.className = cls; 
     2232    lineView.text.className = cls 
    22382233  } 
    22392234} 
    22402235 
    22412236function updateLineClasses(cm, lineView) { 
    2242   updateLineBackground(cm, lineView); 
     2237  updateLineBackground(cm, lineView) 
    22432238  if (lineView.line.wrapClass) 
    2244     { ensureLineWrapped(lineView).className = lineView.line.wrapClass; } 
     2239    { ensureLineWrapped(lineView).className = lineView.line.wrapClass } 
    22452240  else if (lineView.node != lineView.text) 
    2246     { lineView.node.className = ""; } 
    2247   var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; 
    2248   lineView.text.className = textClass || ""; 
     2241    { lineView.node.className = "" } 
     2242  var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass 
     2243  lineView.text.className = textClass || "" 
    22492244} 
    22502245 
    22512246function updateLineGutter(cm, lineView, lineN, dims) { 
    22522247  if (lineView.gutter) { 
    2253     lineView.node.removeChild(lineView.gutter); 
    2254     lineView.gutter = null; 
     2248    lineView.node.removeChild(lineView.gutter) 
     2249    lineView.gutter = null 
    22552250  } 
    22562251  if (lineView.gutterBackground) { 
    2257     lineView.node.removeChild(lineView.gutterBackground); 
    2258     lineView.gutterBackground = null; 
     2252    lineView.node.removeChild(lineView.gutterBackground) 
     2253    lineView.gutterBackground = null 
    22592254  } 
    22602255  if (lineView.line.gutterClass) { 
    2261     var wrap = ensureLineWrapped(lineView); 
     2256    var wrap = ensureLineWrapped(lineView) 
    22622257    lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, 
    2263                                     ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px")); 
    2264     cm.display.input.setUneditable(lineView.gutterBackground); 
    2265     wrap.insertBefore(lineView.gutterBackground, lineView.text); 
    2266   } 
    2267   var markers = lineView.line.gutterMarkers; 
     2258                                    ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px")) 
     2259    cm.display.input.setUneditable(lineView.gutterBackground) 
     2260    wrap.insertBefore(lineView.gutterBackground, lineView.text) 
     2261  } 
     2262  var markers = lineView.line.gutterMarkers 
    22682263  if (cm.options.lineNumbers || markers) { 
    2269     var wrap$1 = ensureLineWrapped(lineView); 
    2270     var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px")); 
    2271     cm.display.input.setUneditable(gutterWrap); 
    2272     wrap$1.insertBefore(gutterWrap, lineView.text); 
     2264    var wrap$1 = ensureLineWrapped(lineView) 
     2265    var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px")) 
     2266    cm.display.input.setUneditable(gutterWrap) 
     2267    wrap$1.insertBefore(gutterWrap, lineView.text) 
    22732268    if (lineView.line.gutterClass) 
    2274       { gutterWrap.className += " " + lineView.line.gutterClass; } 
     2269      { gutterWrap.className += " " + lineView.line.gutterClass } 
    22752270    if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) 
    22762271      { lineView.lineNumber = gutterWrap.appendChild( 
    22772272        elt("div", lineNumberFor(cm.options, lineN), 
    22782273            "CodeMirror-linenumber CodeMirror-gutter-elt", 
    2279             ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); } 
     2274            ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))) } 
    22802275    if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) { 
    2281       var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; 
     2276      var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id] 
    22822277      if (found) 
    22832278        { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", 
    2284                                    ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); } 
     2279                                   ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))) } 
    22852280    } } 
    22862281  } 
     
    22882283 
    22892284function updateLineWidgets(cm, lineView, dims) { 
    2290   if (lineView.alignable) { lineView.alignable = null; } 
     2285  if (lineView.alignable) { lineView.alignable = null } 
    22912286  for (var node = lineView.node.firstChild, next = (void 0); node; node = next) { 
    2292     next = node.nextSibling; 
     2287    next = node.nextSibling 
    22932288    if (node.className == "CodeMirror-linewidget") 
    2294       { lineView.node.removeChild(node); } 
    2295   } 
    2296   insertLineWidgets(cm, lineView, dims); 
     2289      { lineView.node.removeChild(node) } 
     2290  } 
     2291  insertLineWidgets(cm, lineView, dims) 
    22972292} 
    22982293 
    22992294// Build a line's DOM representation from scratch 
    23002295function buildLineElement(cm, lineView, lineN, dims) { 
    2301   var built = getLineContent(cm, lineView); 
    2302   lineView.text = lineView.node = built.pre; 
    2303   if (built.bgClass) { lineView.bgClass = built.bgClass; } 
    2304   if (built.textClass) { lineView.textClass = built.textClass; } 
    2305  
    2306   updateLineClasses(cm, lineView); 
    2307   updateLineGutter(cm, lineView, lineN, dims); 
    2308   insertLineWidgets(cm, lineView, dims); 
     2296  var built = getLineContent(cm, lineView) 
     2297  lineView.text = lineView.node = built.pre 
     2298  if (built.bgClass) { lineView.bgClass = built.bgClass } 
     2299  if (built.textClass) { lineView.textClass = built.textClass } 
     2300 
     2301  updateLineClasses(cm, lineView) 
     2302  updateLineGutter(cm, lineView, lineN, dims) 
     2303  insertLineWidgets(cm, lineView, dims) 
    23092304  return lineView.node 
    23102305} 
     
    23132308// collapsed spans). The widgets for all of them need to be drawn. 
    23142309function insertLineWidgets(cm, lineView, dims) { 
    2315   insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); 
     2310  insertLineWidgetsFor(cm, lineView.line, lineView, dims, true) 
    23162311  if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) 
    2317     { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } } 
     2312    { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false) } } 
    23182313} 
    23192314 
    23202315function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { 
    23212316  if (!line.widgets) { return } 
    2322   var wrap = ensureLineWrapped(lineView); 
     2317  var wrap = ensureLineWrapped(lineView) 
    23232318  for (var i = 0, ws = line.widgets; i < ws.length; ++i) { 
    2324     var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); 
    2325     if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); } 
    2326     positionLineWidget(widget, node, lineView, dims); 
    2327     cm.display.input.setUneditable(node); 
     2319    var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget") 
     2320    if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true") } 
     2321    positionLineWidget(widget, node, lineView, dims) 
     2322    cm.display.input.setUneditable(node) 
    23282323    if (allowAbove && widget.above) 
    2329       { wrap.insertBefore(node, lineView.gutter || lineView.text); } 
     2324      { wrap.insertBefore(node, lineView.gutter || lineView.text) } 
    23302325    else 
    2331       { wrap.appendChild(node); } 
    2332     signalLater(widget, "redraw"); 
     2326      { wrap.appendChild(node) } 
     2327    signalLater(widget, "redraw") 
    23332328  } 
    23342329} 
     
    23362331function positionLineWidget(widget, node, lineView, dims) { 
    23372332  if (widget.noHScroll) { 
    2338     (lineView.alignable || (lineView.alignable = [])).push(node); 
    2339     var width = dims.wrapperWidth; 
    2340     node.style.left = dims.fixedPos + "px"; 
     2333    ;(lineView.alignable || (lineView.alignable = [])).push(node) 
     2334    var width = dims.wrapperWidth 
     2335    node.style.left = dims.fixedPos + "px" 
    23412336    if (!widget.coverGutter) { 
    2342       width -= dims.gutterTotalWidth; 
    2343       node.style.paddingLeft = dims.gutterTotalWidth + "px"; 
    2344     } 
    2345     node.style.width = width + "px"; 
     2337      width -= dims.gutterTotalWidth 
     2338      node.style.paddingLeft = dims.gutterTotalWidth + "px" 
     2339    } 
     2340    node.style.width = width + "px" 
    23462341  } 
    23472342  if (widget.coverGutter) { 
    2348     node.style.zIndex = 5; 
    2349     node.style.position = "relative"; 
    2350     if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; } 
     2343    node.style.zIndex = 5 
     2344    node.style.position = "relative" 
     2345    if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px" } 
    23512346  } 
    23522347} 
     
    23542349function widgetHeight(widget) { 
    23552350  if (widget.height != null) { return widget.height } 
    2356   var cm = widget.doc.cm; 
     2351  var cm = widget.doc.cm 
    23572352  if (!cm) { return 0 } 
    23582353  if (!contains(document.body, widget.node)) { 
    2359     var parentStyle = "position: relative;"; 
     2354    var parentStyle = "position: relative;" 
    23602355    if (widget.coverGutter) 
    2361       { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; } 
     2356      { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;" } 
    23622357    if (widget.noHScroll) 
    2363       { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; } 
    2364     removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); 
     2358      { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;" } 
     2359    removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)) 
    23652360  } 
    23662361  return widget.height = widget.node.parentNode.offsetHeight 
     
    23822377function paddingH(display) { 
    23832378  if (display.cachedPaddingH) { return display.cachedPaddingH } 
    2384   var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); 
    2385   var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; 
    2386   var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; 
    2387   if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; } 
     2379  var e = removeChildrenAndAdd(display.measure, elt("pre", "x")) 
     2380  var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle 
     2381  var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)} 
     2382  if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data } 
    23882383  return data 
    23892384} 
     
    24022397// height. 
    24032398function ensureLineHeights(cm, lineView, rect) { 
    2404   var wrapping = cm.options.lineWrapping; 
    2405   var curWidth = wrapping && displayWidth(cm); 
     2399  var wrapping = cm.options.lineWrapping 
     2400  var curWidth = wrapping && displayWidth(cm) 
    24062401  if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { 
    2407     var heights = lineView.measure.heights = []; 
     2402    var heights = lineView.measure.heights = [] 
    24082403    if (wrapping) { 
    2409       lineView.measure.width = curWidth; 
    2410       var rects = lineView.text.firstChild.getClientRects(); 
     2404      lineView.measure.width = curWidth 
     2405      var rects = lineView.text.firstChild.getClientRects() 
    24112406      for (var i = 0; i < rects.length - 1; i++) { 
    2412         var cur = rects[i], next = rects[i + 1]; 
     2407        var cur = rects[i], next = rects[i + 1] 
    24132408        if (Math.abs(cur.bottom - next.bottom) > 2) 
    2414           { heights.push((cur.bottom + next.top) / 2 - rect.top); } 
     2409          { heights.push((cur.bottom + next.top) / 2 - rect.top) } 
    24152410      } 
    24162411    } 
    2417     heights.push(rect.bottom - rect.top); 
     2412    heights.push(rect.bottom - rect.top) 
    24182413  } 
    24192414} 
     
    24362431// when measurement is needed for a line that's not in the viewport. 
    24372432function updateExternalMeasurement(cm, line) { 
    2438   line = visualLine(line); 
    2439   var lineN = lineNo(line); 
    2440   var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); 
    2441   view.lineN = lineN; 
    2442   var built = view.built = buildLineContent(cm, view); 
    2443   view.text = built.pre; 
    2444   removeChildrenAndAdd(cm.display.lineMeasure, built.pre); 
     2433  line = visualLine(line) 
     2434  var lineN = lineNo(line) 
     2435  var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN) 
     2436  view.lineN = lineN 
     2437  var built = view.built = buildLineContent(cm, view) 
     2438  view.text = built.pre 
     2439  removeChildrenAndAdd(cm.display.lineMeasure, built.pre) 
    24452440  return view 
    24462441} 
     
    24562451  if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) 
    24572452    { return cm.display.view[findViewIndex(cm, lineN)] } 
    2458   var ext = cm.display.externalMeasured; 
     2453  var ext = cm.display.externalMeasured 
    24592454  if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) 
    24602455    { return ext } 
     
    24672462// only done once. 
    24682463function prepareMeasureForLine(cm, line) { 
    2469   var lineN = lineNo(line); 
    2470   var view = findViewForLine(cm, lineN); 
     2464  var lineN = lineNo(line) 
     2465  var view = findViewForLine(cm, lineN) 
    24712466  if (view && !view.text) { 
    2472     view = null; 
     2467    view = null 
    24732468  } else if (view && view.changes) { 
    2474     updateLineForChanges(cm, view, lineN, getDimensions(cm)); 
    2475     cm.curOp.forceUpdate = true; 
     2469    updateLineForChanges(cm, view, lineN, getDimensions(cm)) 
     2470    cm.curOp.forceUpdate = true 
    24762471  } 
    24772472  if (!view) 
    2478     { view = updateExternalMeasurement(cm, line); } 
    2479  
    2480   var info = mapFromLineView(view, line, lineN); 
     2473    { view = updateExternalMeasurement(cm, line) } 
     2474 
     2475  var info = mapFromLineView(view, line, lineN) 
    24812476  return { 
    24822477    line: line, view: view, rect: null, 
     
    24892484// actual character (or fetches it from the cache). 
    24902485function measureCharPrepared(cm, prepared, ch, bias, varHeight) { 
    2491   if (prepared.before) { ch = -1; } 
    2492   var key = ch + (bias || ""), found; 
     2486  if (prepared.before) { ch = -1 } 
     2487  var key = ch + (bias || ""), found 
    24932488  if (prepared.cache.hasOwnProperty(key)) { 
    2494     found = prepared.cache[key]; 
     2489    found = prepared.cache[key] 
    24952490  } else { 
    24962491    if (!prepared.rect) 
    2497       { prepared.rect = prepared.view.text.getBoundingClientRect(); } 
     2492      { prepared.rect = prepared.view.text.getBoundingClientRect() } 
    24982493    if (!prepared.hasHeights) { 
    2499       ensureLineHeights(cm, prepared.view, prepared.rect); 
    2500       prepared.hasHeights = true; 
    2501     } 
    2502     found = measureCharInner(cm, prepared, ch, bias); 
    2503     if (!found.bogus) { prepared.cache[key] = found; } 
     2494      ensureLineHeights(cm, prepared.view, prepared.rect) 
     2495      prepared.hasHeights = true 
     2496    } 
     2497    found = measureCharInner(cm, prepared, ch, bias) 
     2498    if (!found.bogus) { prepared.cache[key] = found } 
    25042499  } 
    25052500  return {left: found.left, right: found.right, 
     
    25082503} 
    25092504 
    2510 var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; 
    2511  
    2512 function nodeAndOffsetInLineMap(map$$1, ch, bias) { 
    2513   var node, start, end, collapse, mStart, mEnd; 
     2505var nullRect = {left: 0, right: 0, top: 0, bottom: 0} 
     2506 
     2507function nodeAndOffsetInLineMap(map, ch, bias) { 
     2508  var node, start, end, collapse, mStart, mEnd 
    25142509  // First, search the line map for the text node corresponding to, 
    25152510  // or closest to, the target character. 
    2516   for (var i = 0; i < map$$1.length; i += 3) { 
    2517     mStart = map$$1[i]; 
    2518     mEnd = map$$1[i + 1]; 
     2511  for (var i = 0; i < map.length; i += 3) { 
     2512    mStart = map[i] 
     2513    mEnd = map[i + 1] 
    25192514    if (ch < mStart) { 
    2520       start = 0; end = 1; 
    2521       collapse = "left"; 
     2515      start = 0; end = 1 
     2516      collapse = "left" 
    25222517    } else if (ch < mEnd) { 
    2523       start = ch - mStart; 
    2524       end = start + 1; 
    2525     } else if (i == map$$1.length - 3 || ch == mEnd && map$$1[i + 3] > ch) { 
    2526       end = mEnd - mStart; 
    2527       start = end - 1; 
    2528       if (ch >= mEnd) { collapse = "right"; } 
     2518      start = ch - mStart 
     2519      end = start + 1 
     2520    } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { 
     2521      end = mEnd - mStart 
     2522      start = end - 1 
     2523      if (ch >= mEnd) { collapse = "right" } 
    25292524    } 
    25302525    if (start != null) { 
    2531       node = map$$1[i + 2]; 
     2526      node = map[i + 2] 
    25322527      if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) 
    2533         { collapse = bias; } 
     2528        { collapse = bias } 
    25342529      if (bias == "left" && start == 0) 
    2535         { while (i && map$$1[i - 2] == map$$1[i - 3] && map$$1[i - 1].insertLeft) { 
    2536           node = map$$1[(i -= 3) + 2]; 
    2537           collapse = "left"; 
     2530        { while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { 
     2531          node = map[(i -= 3) + 2] 
     2532          collapse = "left" 
    25382533        } } 
    25392534      if (bias == "right" && start == mEnd - mStart) 
    2540         { while (i < map$$1.length - 3 && map$$1[i + 3] == map$$1[i + 4] && !map$$1[i + 5].insertLeft) { 
    2541           node = map$$1[(i += 3) + 2]; 
    2542           collapse = "right"; 
     2535        { while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { 
     2536          node = map[(i += 3) + 2] 
     2537          collapse = "right" 
    25432538        } } 
    25442539      break 
     
    25492544 
    25502545function getUsefulRect(rects, bias) { 
    2551   var rect = nullRect; 
     2546  var rect = nullRect 
    25522547  if (bias == "left") { for (var i = 0; i < rects.length; i++) { 
    25532548    if ((rect = rects[i]).left != rect.right) { break } 
     
    25592554 
    25602555function measureCharInner(cm, prepared, ch, bias) { 
    2561   var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); 
    2562   var node = place.node, start = place.start, end = place.end, collapse = place.collapse; 
    2563  
    2564   var rect; 
     2556  var place = nodeAndOffsetInLineMap(prepared.map, ch, bias) 
     2557  var node = place.node, start = place.start, end = place.end, collapse = place.collapse 
     2558 
     2559  var rect 
    25652560  if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. 
    25662561    for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned 
    2567       while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; } 
    2568       while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; } 
     2562      while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start } 
     2563      while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end } 
    25692564      if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) 
    2570         { rect = node.parentNode.getBoundingClientRect(); } 
     2565        { rect = node.parentNode.getBoundingClientRect() } 
    25712566      else 
    2572         { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); } 
     2567        { rect = getUsefulRect(range(node, start, end).getClientRects(), bias) } 
    25732568      if (rect.left || rect.right || start == 0) { break } 
    2574       end = start; 
    2575       start = start - 1; 
    2576       collapse = "right"; 
    2577     } 
    2578     if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); } 
     2569      end = start 
     2570      start = start - 1 
     2571      collapse = "right" 
     2572    } 
     2573    if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect) } 
    25792574  } else { // If it is a widget, simply get the box for the whole widget. 
    2580     if (start > 0) { collapse = bias = "right"; } 
    2581     var rects; 
     2575    if (start > 0) { collapse = bias = "right" } 
     2576    var rects 
    25822577    if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) 
    2583       { rect = rects[bias == "right" ? rects.length - 1 : 0]; } 
     2578      { rect = rects[bias == "right" ? rects.length - 1 : 0] } 
    25842579    else 
    2585       { rect = node.getBoundingClientRect(); } 
     2580      { rect = node.getBoundingClientRect() } 
    25862581  } 
    25872582  if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { 
    2588     var rSpan = node.parentNode.getClientRects()[0]; 
     2583    var rSpan = node.parentNode.getClientRects()[0] 
    25892584    if (rSpan) 
    2590       { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; } 
     2585      { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom} } 
    25912586    else 
    2592       { rect = nullRect; } 
    2593   } 
    2594  
    2595   var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; 
    2596   var mid = (rtop + rbot) / 2; 
    2597   var heights = prepared.view.measure.heights; 
    2598   var i = 0; 
     2587      { rect = nullRect } 
     2588  } 
     2589 
     2590  var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top 
     2591  var mid = (rtop + rbot) / 2 
     2592  var heights = prepared.view.measure.heights 
     2593  var i = 0 
    25992594  for (; i < heights.length - 1; i++) 
    26002595    { if (mid < heights[i]) { break } } 
    2601   var top = i ? heights[i - 1] : 0, bot = heights[i]; 
     2596  var top = i ? heights[i - 1] : 0, bot = heights[i] 
    26022597  var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, 
    26032598                right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, 
    2604                 top: top, bottom: bot}; 
    2605   if (!rect.left && !rect.right) { result.bogus = true; } 
    2606   if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } 
     2599                top: top, bottom: bot} 
     2600  if (!rect.left && !rect.right) { result.bogus = true } 
     2601  if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot } 
    26072602 
    26082603  return result 
     
    26152610      screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) 
    26162611    { return rect } 
    2617   var scaleX = screen.logicalXDPI / screen.deviceXDPI; 
    2618   var scaleY = screen.logicalYDPI / screen.deviceYDPI; 
     2612  var scaleX = screen.logicalXDPI / screen.deviceXDPI 
     2613  var scaleY = screen.logicalYDPI / screen.deviceYDPI 
    26192614  return {left: rect.left * scaleX, right: rect.right * scaleX, 
    26202615          top: rect.top * scaleY, bottom: rect.bottom * scaleY} 
     
    26232618function clearLineMeasurementCacheFor(lineView) { 
    26242619  if (lineView.measure) { 
    2625     lineView.measure.cache = {}; 
    2626     lineView.measure.heights = null; 
     2620    lineView.measure.cache = {} 
     2621    lineView.measure.heights = null 
    26272622    if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) 
    2628       { lineView.measure.caches[i] = {}; } } 
     2623      { lineView.measure.caches[i] = {} } } 
    26292624  } 
    26302625} 
    26312626 
    26322627function clearLineMeasurementCache(cm) { 
    2633   cm.display.externalMeasure = null; 
    2634   removeChildren(cm.display.lineMeasure); 
     2628  cm.display.externalMeasure = null 
     2629  removeChildren(cm.display.lineMeasure) 
    26352630  for (var i = 0; i < cm.display.view.length; i++) 
    2636     { clearLineMeasurementCacheFor(cm.display.view[i]); } 
     2631    { clearLineMeasurementCacheFor(cm.display.view[i]) } 
    26372632} 
    26382633 
    26392634function clearCaches(cm) { 
    2640   clearLineMeasurementCache(cm); 
    2641   cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; 
    2642   if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; } 
    2643   cm.display.lineNumChars = null; 
    2644 } 
    2645  
    2646 function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft } 
    2647 function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop } 
     2635  clearLineMeasurementCache(cm) 
     2636  cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null 
     2637  if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true } 
     2638  cm.display.lineNumChars = null 
     2639} 
     2640 
     2641function pageScrollX() { 
     2642  // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 
     2643  // which causes page_Offset and bounding client rects to use 
     2644  // different reference viewports and invalidate our calculations. 
     2645  if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) } 
     2646  return window.pageXOffset || (document.documentElement || document.body).scrollLeft 
     2647} 
     2648function pageScrollY() { 
     2649  if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) } 
     2650  return window.pageYOffset || (document.documentElement || document.body).scrollTop 
     2651} 
     2652 
     2653function widgetTopHeight(lineObj) { 
     2654  var height = 0 
     2655  if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) 
     2656    { height += widgetHeight(lineObj.widgets[i]) } } } 
     2657  return height 
     2658} 
    26482659 
    26492660// Converts a {top, bottom, left, right} box from line-local 
     
    26522663// or "page". 
    26532664function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) { 
    2654   if (!includeWidgets && lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) { 
    2655     var size = widgetHeight(lineObj.widgets[i]); 
    2656     rect.top += size; rect.bottom += size; 
    2657   } } } 
     2665  if (!includeWidgets) { 
     2666    var height = widgetTopHeight(lineObj) 
     2667    rect.top += height; rect.bottom += height 
     2668  } 
    26582669  if (context == "line") { return rect } 
    2659   if (!context) { context = "local"; } 
    2660   var yOff = heightAtLine(lineObj); 
    2661   if (context == "local") { yOff += paddingTop(cm.display); } 
    2662   else { yOff -= cm.display.viewOffset; } 
     2670  if (!context) { context = "local" } 
     2671  var yOff = heightAtLine(lineObj) 
     2672  if (context == "local") { yOff += paddingTop(cm.display) } 
     2673  else { yOff -= cm.display.viewOffset } 
    26632674  if (context == "page" || context == "window") { 
    2664     var lOff = cm.display.lineSpace.getBoundingClientRect(); 
    2665     yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); 
    2666     var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); 
    2667     rect.left += xOff; rect.right += xOff; 
    2668   } 
    2669   rect.top += yOff; rect.bottom += yOff; 
     2675    var lOff = cm.display.lineSpace.getBoundingClientRect() 
     2676    yOff += lOff.top + (context == "window" ? 0 : pageScrollY()) 
     2677    var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()) 
     2678    rect.left += xOff; rect.right += xOff 
     2679  } 
     2680  rect.top += yOff; rect.bottom += yOff 
    26702681  return rect 
    26712682} 
     
    26752686function fromCoordSystem(cm, coords, context) { 
    26762687  if (context == "div") { return coords } 
    2677   var left = coords.left, top = coords.top; 
     2688  var left = coords.left, top = coords.top 
    26782689  // First move into "page" coordinate system 
    26792690  if (context == "page") { 
    2680     left -= pageScrollX(); 
    2681     top -= pageScrollY(); 
     2691    left -= pageScrollX() 
     2692    top -= pageScrollY() 
    26822693  } else if (context == "local" || !context) { 
    2683     var localBox = cm.display.sizer.getBoundingClientRect(); 
    2684     left += localBox.left; 
    2685     top += localBox.top; 
    2686   } 
    2687  
    2688   var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); 
     2694    var localBox = cm.display.sizer.getBoundingClientRect() 
     2695    left += localBox.left 
     2696    top += localBox.top 
     2697  } 
     2698 
     2699  var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect() 
    26892700  return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top} 
    26902701} 
    26912702 
    26922703function charCoords(cm, pos, context, lineObj, bias) { 
    2693   if (!lineObj) { lineObj = getLine(cm.doc, pos.line); } 
     2704  if (!lineObj) { lineObj = getLine(cm.doc, pos.line) } 
    26942705  return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context) 
    26952706} 
     
    27122723// to the last character on the line. 
    27132724function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { 
    2714   lineObj = lineObj || getLine(cm.doc, pos.line); 
    2715   if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); } 
     2725  lineObj = lineObj || getLine(cm.doc, pos.line) 
     2726  if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) } 
    27162727  function get(ch, right) { 
    2717     var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); 
    2718     if (right) { m.left = m.right; } else { m.right = m.left; } 
     2728    var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight) 
     2729    if (right) { m.left = m.right; } else { m.right = m.left } 
    27192730    return intoCoordSystem(cm, lineObj, m, context) 
    27202731  } 
    2721   var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky; 
     2732  var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky 
    27222733  if (ch >= lineObj.text.length) { 
    2723     ch = lineObj.text.length; 
    2724     sticky = "before"; 
     2734    ch = lineObj.text.length 
     2735    sticky = "before" 
    27252736  } else if (ch <= 0) { 
    2726     ch = 0; 
    2727     sticky = "after"; 
     2737    ch = 0 
     2738    sticky = "after" 
    27282739  } 
    27292740  if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") } 
    27302741 
    27312742  function getBidi(ch, partPos, invert) { 
    2732     var part = order[partPos], right = (part.level % 2) != 0; 
     2743    var part = order[partPos], right = part.level == 1 
    27332744    return get(invert ? ch - 1 : ch, right != invert) 
    27342745  } 
    2735   var partPos = getBidiPartAt(order, ch, sticky); 
    2736   var other = bidiOther; 
    2737   var val = getBidi(ch, partPos, sticky == "before"); 
    2738   if (other != null) { val.other = getBidi(ch, other, sticky != "before"); } 
     2746  var partPos = getBidiPartAt(order, ch, sticky) 
     2747  var other = bidiOther 
     2748  var val = getBidi(ch, partPos, sticky == "before") 
     2749  if (other != null) { val.other = getBidi(ch, other, sticky != "before") } 
    27392750  return val 
    27402751} 
     
    27432754// intermediate scroll updates. 
    27442755function estimateCoords(cm, pos) { 
    2745   var left = 0; 
    2746   pos = clipPos(cm.doc, pos); 
    2747   if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; } 
    2748   var lineObj = getLine(cm.doc, pos.line); 
    2749   var top = heightAtLine(lineObj) + paddingTop(cm.display); 
     2756  var left = 0 
     2757  pos = clipPos(cm.doc, pos) 
     2758  if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch } 
     2759  var lineObj = getLine(cm.doc, pos.line) 
     2760  var top = heightAtLine(lineObj) + paddingTop(cm.display) 
    27502761  return {left: left, right: left, top: top, bottom: top + lineObj.height} 
    27512762} 
     
    27582769// vertical range. 
    27592770function PosWithInfo(line, ch, sticky, outside, xRel) { 
    2760   var pos = Pos(line, ch, sticky); 
    2761   pos.xRel = xRel; 
    2762   if (outside) { pos.outside = true; } 
     2771  var pos = Pos(line, ch, sticky) 
     2772  pos.xRel = xRel 
     2773  if (outside) { pos.outside = true } 
    27632774  return pos 
    27642775} 
     
    27672778// Input must be lineSpace-local ("div" coordinate system). 
    27682779function coordsChar(cm, x, y) { 
    2769   var doc = cm.doc; 
    2770   y += cm.display.viewOffset; 
     2780  var doc = cm.doc 
     2781  y += cm.display.viewOffset 
    27712782  if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) } 
    2772   var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; 
     2783  var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1 
    27732784  if (lineN > last) 
    27742785    { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) } 
    2775   if (x < 0) { x = 0; } 
    2776  
    2777   var lineObj = getLine(doc, lineN); 
     2786  if (x < 0) { x = 0 } 
     2787 
     2788  var lineObj = getLine(doc, lineN) 
    27782789  for (;;) { 
    2779     var found = coordsCharInner(cm, lineObj, lineN, x, y); 
    2780     var merged = collapsedSpanAtEnd(lineObj); 
    2781     var mergedPos = merged && merged.find(0, true); 
    2782     if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) 
    2783       { lineN = lineNo(lineObj = mergedPos.to.line); } 
    2784     else 
    2785       { return found } 
     2790    var found = coordsCharInner(cm, lineObj, lineN, x, y) 
     2791    var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0)) 
     2792    if (!collapsed) { return found } 
     2793    var rangeEnd = collapsed.find(1) 
     2794    if (rangeEnd.line == lineN) { return rangeEnd } 
     2795    lineObj = getLine(doc, lineN = rangeEnd.line) 
    27862796  } 
    27872797} 
    27882798 
    27892799function wrappedLineExtent(cm, lineObj, preparedMeasure, y) { 
    2790   var measure = function (ch) { return intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); }; 
    2791   var end = lineObj.text.length; 
    2792   var begin = findFirst(function (ch) { return measure(ch - 1).bottom <= y; }, end, 0); 
    2793   end = findFirst(function (ch) { return measure(ch).top > y; }, begin, end); 
     2800  y -= widgetTopHeight(lineObj) 
     2801  var end = lineObj.text.length 
     2802  var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0) 
     2803  end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end) 
    27942804  return {begin: begin, end: end} 
    27952805} 
    27962806 
    27972807function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) { 
    2798   var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top; 
     2808  if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) } 
     2809  var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top 
    27992810  return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop) 
    28002811} 
    28012812 
    2802 function coordsCharInner(cm, lineObj, lineNo$$1, x, y) { 
    2803   y -= heightAtLine(lineObj); 
    2804   var begin = 0, end = lineObj.text.length; 
    2805   var preparedMeasure = prepareMeasureForLine(cm, lineObj); 
    2806   var pos; 
    2807   var order = getOrder(lineObj, cm.doc.direction); 
     2813// Returns true if the given side of a box is after the given 
     2814// coordinates, in top-to-bottom, left-to-right order. 
     2815function boxIsAfter(box, x, y, left) { 
     2816  return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x 
     2817} 
     2818 
     2819function coordsCharInner(cm, lineObj, lineNo, x, y) { 
     2820  // Move y into line-local coordinate space 
     2821  y -= heightAtLine(lineObj) 
     2822  var preparedMeasure = prepareMeasureForLine(cm, lineObj) 
     2823  // When directly calling `measureCharPrepared`, we have to adjust 
     2824  // for the widgets at this line. 
     2825  var widgetHeight = widgetTopHeight(lineObj) 
     2826  var begin = 0, end = lineObj.text.length, ltr = true 
     2827 
     2828  var order = getOrder(lineObj, cm.doc.direction) 
     2829  // If the line isn't plain left-to-right text, first figure out 
     2830  // which bidi section the coordinates fall into. 
    28082831  if (order) { 
    2809     if (cm.options.lineWrapping) { 
    2810       var assign; 
    2811       ((assign = wrappedLineExtent(cm, lineObj, preparedMeasure, y), begin = assign.begin, end = assign.end)); 
    2812     } 
    2813     pos = new Pos(lineNo$$1, begin); 
    2814     var beginLeft = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left; 
    2815     var dir = beginLeft < x ? 1 : -1; 
    2816     var prevDiff, diff = beginLeft - x, prevPos; 
    2817     do { 
    2818       prevDiff = diff; 
    2819       prevPos = pos; 
    2820       pos = moveVisually(cm, lineObj, pos, dir); 
    2821       if (pos == null || pos.ch < begin || end <= (pos.sticky == "before" ? pos.ch - 1 : pos.ch)) { 
    2822         pos = prevPos; 
    2823         break 
    2824       } 
    2825       diff = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left - x; 
    2826     } while ((dir < 0) != (diff < 0) && (Math.abs(diff) <= Math.abs(prevDiff))) 
    2827     if (Math.abs(diff) > Math.abs(prevDiff)) { 
    2828       if ((diff < 0) == (prevDiff < 0)) { throw new Error("Broke out of infinite loop in coordsCharInner") } 
    2829       pos = prevPos; 
    2830     } 
     2832    var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart) 
     2833                 (cm, lineObj, lineNo, preparedMeasure, order, x, y) 
     2834    ltr = part.level != 1 
     2835    // The awkward -1 offsets are needed because findFirst (called 
     2836    // on these below) will treat its first bound as inclusive, 
     2837    // second as exclusive, but we want to actually address the 
     2838    // characters in the part's range 
     2839    begin = ltr ? part.from : part.to - 1 
     2840    end = ltr ? part.to : part.from - 1 
     2841  } 
     2842 
     2843  // A binary search to find the first character whose bounding box 
     2844  // starts after the coordinates. If we run across any whose box wrap 
     2845  // the coordinates, store that. 
     2846  var chAround = null, boxAround = null 
     2847  var ch = findFirst(function (ch) { 
     2848    var box = measureCharPrepared(cm, preparedMeasure, ch) 
     2849    box.top += widgetHeight; box.bottom += widgetHeight 
     2850    if (!boxIsAfter(box, x, y, false)) { return false } 
     2851    if (box.top <= y && box.left <= x) { 
     2852      chAround = ch 
     2853      boxAround = box 
     2854    } 
     2855    return true 
     2856  }, begin, end) 
     2857 
     2858  var baseX, sticky, outside = false 
     2859  // If a box around the coordinates was found, use that 
     2860  if (boxAround) { 
     2861    // Distinguish coordinates nearer to the left or right side of the box 
     2862    var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr 
     2863    ch = chAround + (atStart ? 0 : 1) 
     2864    sticky = atStart ? "after" : "before" 
     2865    baseX = atLeft ? boxAround.left : boxAround.right 
    28312866  } else { 
    2832     var ch = findFirst(function (ch) { 
    2833       var box = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); 
    2834       if (box.top > y) { 
    2835         // For the cursor stickiness 
    2836         end = Math.min(ch, end); 
    2837         return true 
    2838       } 
    2839       else if (box.bottom <= y) { return false } 
    2840       else if (box.left > x) { return true } 
    2841       else if (box.right < x) { return false } 
    2842       else { return (x - box.left < box.right - x) } 
    2843     }, begin, end); 
    2844     ch = skipExtendingChars(lineObj.text, ch, 1); 
    2845     pos = new Pos(lineNo$$1, ch, ch == end ? "before" : "after"); 
    2846   } 
    2847   var coords = cursorCoords(cm, pos, "line", lineObj, preparedMeasure); 
    2848   if (y < coords.top || coords.bottom < y) { pos.outside = true; } 
    2849   pos.xRel = x < coords.left ? -1 : (x > coords.right ? 1 : 0); 
    2850   return pos 
    2851 } 
    2852  
    2853 var measureText; 
     2867    // (Adjust for extended bound, if necessary.) 
     2868    if (!ltr && (ch == end || ch == begin)) { ch++ } 
     2869    // To determine which side to associate with, get the box to the 
     2870    // left of the character and compare it's vertical position to the 
     2871    // coordinates 
     2872    sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" : 
     2873      (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight <= y) == ltr ? 
     2874      "after" : "before" 
     2875    // Now get accurate coordinates for this place, in order to get a 
     2876    // base X position 
     2877    var coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure) 
     2878    baseX = coords.left 
     2879    outside = y < coords.top || y >= coords.bottom 
     2880  } 
     2881 
     2882  ch = skipExtendingChars(lineObj.text, ch, 1) 
     2883  return PosWithInfo(lineNo, ch, sticky, outside, x - baseX) 
     2884} 
     2885 
     2886function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, y) { 
     2887  // Bidi parts are sorted left-to-right, and in a non-line-wrapping 
     2888  // situation, we can take this ordering to correspond to the visual 
     2889  // ordering. This finds the first part whose end is after the given 
     2890  // coordinates. 
     2891  var index = findFirst(function (i) { 
     2892    var part = order[i], ltr = part.level != 1 
     2893    return boxIsAfter(cursorCoords(cm, Pos(lineNo, ltr ? part.to : part.from, ltr ? "before" : "after"), 
     2894                                   "line", lineObj, preparedMeasure), x, y, true) 
     2895  }, 0, order.length - 1) 
     2896  var part = order[index] 
     2897  // If this isn't the first part, the part's start is also after 
     2898  // the coordinates, and the coordinates aren't on the same line as 
     2899  // that start, move one part back. 
     2900  if (index > 0) { 
     2901    var ltr = part.level != 1 
     2902    var start = cursorCoords(cm, Pos(lineNo, ltr ? part.from : part.to, ltr ? "after" : "before"), 
     2903                             "line", lineObj, preparedMeasure) 
     2904    if (boxIsAfter(start, x, y, true) && start.top > y) 
     2905      { part = order[index - 1] } 
     2906  } 
     2907  return part 
     2908} 
     2909 
     2910function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) { 
     2911  // In a wrapped line, rtl text on wrapping boundaries can do things 
     2912  // that don't correspond to the ordering in our `order` array at 
     2913  // all, so a binary search doesn't work, and we want to return a 
     2914  // part that only spans one line so that the binary search in 
     2915  // coordsCharInner is safe. As such, we first find the extent of the 
     2916  // wrapped line, and then do a flat search in which we discard any 
     2917  // spans that aren't on the line. 
     2918  var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y); 
     2919  var begin = ref.begin; 
     2920  var end = ref.end; 
     2921  if (/\s/.test(lineObj.text.charAt(end - 1))) { end-- } 
     2922  var part = null, closestDist = null 
     2923  for (var i = 0; i < order.length; i++) { 
     2924    var p = order[i] 
     2925    if (p.from >= end || p.to <= begin) { continue } 
     2926    var ltr = p.level != 1 
     2927    var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right 
     2928    // Weigh against spans ending before this, so that they are only 
     2929    // picked if nothing ends after 
     2930    var dist = endX < x ? x - endX + 1e9 : endX - x 
     2931    if (!part || closestDist > dist) { 
     2932      part = p 
     2933      closestDist = dist 
     2934    } 
     2935  } 
     2936  if (!part) { part = order[order.length - 1] } 
     2937  // Clip the part to the wrapped line. 
     2938  if (part.from < begin) { part = {from: begin, to: part.to, level: part.level} } 
     2939  if (part.to > end) { part = {from: part.from, to: end, level: part.level} } 
     2940  return part 
     2941} 
     2942 
     2943var measureText 
    28542944// Compute the default text height. 
    28552945function textHeight(display) { 
    28562946  if (display.cachedTextHeight != null) { return display.cachedTextHeight } 
    28572947  if (measureText == null) { 
    2858     measureText = elt("pre"); 
     2948    measureText = elt("pre") 
    28592949    // Measure a bunch of lines, for browsers that compute 
    28602950    // fractional heights. 
    28612951    for (var i = 0; i < 49; ++i) { 
    2862       measureText.appendChild(document.createTextNode("x")); 
    2863       measureText.appendChild(elt("br")); 
    2864     } 
    2865     measureText.appendChild(document.createTextNode("x")); 
    2866   } 
    2867   removeChildrenAndAdd(display.measure, measureText); 
    2868   var height = measureText.offsetHeight / 50; 
    2869   if (height > 3) { display.cachedTextHeight = height; } 
    2870   removeChildren(display.measure); 
     2952      measureText.appendChild(document.createTextNode("x")) 
     2953      measureText.appendChild(elt("br")) 
     2954    } 
     2955    measureText.appendChild(document.createTextNode("x")) 
     2956  } 
     2957  removeChildrenAndAdd(display.measure, measureText) 
     2958  var height = measureText.offsetHeight / 50 
     2959  if (height > 3) { display.cachedTextHeight = height } 
     2960  removeChildren(display.measure) 
    28712961  return height || 1 
    28722962} 
     
    28752965function charWidth(display) { 
    28762966  if (display.cachedCharWidth != null) { return display.cachedCharWidth } 
    2877   var anchor = elt("span", "xxxxxxxxxx"); 
    2878   var pre = elt("pre", [anchor]); 
    2879   removeChildrenAndAdd(display.measure, pre); 
    2880   var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; 
    2881   if (width > 2) { display.cachedCharWidth = width; } 
     2967  var anchor = elt("span", "xxxxxxxxxx") 
     2968  var pre = elt("pre", [anchor]) 
     2969  removeChildrenAndAdd(display.measure, pre) 
     2970  var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10 
     2971  if (width > 2) { display.cachedCharWidth = width } 
    28822972  return width || 10 
    28832973} 
     
    28862976// view, so that we don't interleave reading and writing to the DOM. 
    28872977function getDimensions(cm) { 
    2888   var d = cm.display, left = {}, width = {}; 
    2889   var gutterLeft = d.gutters.clientLeft; 
     2978  var d = cm.display, left = {}, width = {} 
     2979  var gutterLeft = d.gutters.clientLeft 
    28902980  for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { 
    2891     left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; 
    2892     width[cm.options.gutters[i]] = n.clientWidth; 
     2981    left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft 
     2982    width[cm.options.gutters[i]] = n.clientWidth 
    28932983  } 
    28942984  return {fixedPos: compensateForHScroll(d), 
     
    29103000// properly measurable). 
    29113001function estimateHeight(cm) { 
    2912   var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; 
    2913   var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); 
     3002  var th = textHeight(cm.display), wrapping = cm.options.lineWrapping 
     3003  var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3) 
    29143004  return function (line) { 
    29153005    if (lineIsHidden(cm.doc, line)) { return 0 } 
    29163006 
    2917     var widgetsHeight = 0; 
     3007    var widgetsHeight = 0 
    29183008    if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) { 
    2919       if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; } 
     3009      if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height } 
    29203010    } } 
    29213011 
     
    29283018 
    29293019function estimateLineHeights(cm) { 
    2930   var doc = cm.doc, est = estimateHeight(cm); 
     3020  var doc = cm.doc, est = estimateHeight(cm) 
    29313021  doc.iter(function (line) { 
    2932     var estHeight = est(line); 
    2933     if (estHeight != line.height) { updateLineHeight(line, estHeight); } 
    2934   }); 
     3022    var estHeight = est(line) 
     3023    if (estHeight != line.height) { updateLineHeight(line, estHeight) } 
     3024  }) 
    29353025} 
    29363026 
     
    29413031// coordinates beyond the right of the text. 
    29423032function posFromMouse(cm, e, liberal, forRect) { 
    2943   var display = cm.display; 
     3033  var display = cm.display 
    29443034  if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null } 
    29453035 
    2946   var x, y, space = display.lineSpace.getBoundingClientRect(); 
     3036  var x, y, space = display.lineSpace.getBoundingClientRect() 
    29473037  // Fails unpredictably on IE[67] when mouse is dragged around quickly. 
    2948   try { x = e.clientX - space.left; y = e.clientY - space.top; } 
     3038  try { x = e.clientX - space.left; y = e.clientY - space.top } 
    29493039  catch (e) { return null } 
    2950   var coords = coordsChar(cm, x, y), line; 
     3040  var coords = coordsChar(cm, x, y), line 
    29513041  if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { 
    2952     var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; 
    2953     coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); 
     3042    var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length 
     3043    coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)) 
    29543044  } 
    29553045  return coords 
     
    29603050function findViewIndex(cm, n) { 
    29613051  if (n >= cm.display.viewTo) { return null } 
    2962   n -= cm.display.viewFrom; 
     3052  n -= cm.display.viewFrom 
    29633053  if (n < 0) { return null } 
    2964   var view = cm.display.view; 
     3054  var view = cm.display.view 
    29653055  for (var i = 0; i < view.length; i++) { 
    2966     n -= view[i].size; 
     3056    n -= view[i].size 
    29673057    if (n < 0) { return i } 
    29683058  } 
     
    29703060 
    29713061function updateSelection(cm) { 
    2972   cm.display.input.showSelection(cm.display.input.prepareSelection()); 
     3062  cm.display.input.showSelection(cm.display.input.prepareSelection()) 
    29733063} 
    29743064 
    29753065function prepareSelection(cm, primary) { 
    2976   var doc = cm.doc, result = {}; 
    2977   var curFragment = result.cursors = document.createDocumentFragment(); 
    2978   var selFragment = result.selection = document.createDocumentFragment(); 
     3066  if ( primary === void 0 ) primary = true; 
     3067 
     3068  var doc = cm.doc, result = {} 
     3069  var curFragment = result.cursors = document.createDocumentFragment() 
     3070  var selFragment = result.selection = document.createDocumentFragment() 
    29793071 
    29803072  for (var i = 0; i < doc.sel.ranges.length; i++) { 
    2981     if (primary === false && i == doc.sel.primIndex) { continue } 
    2982     var range$$1 = doc.sel.ranges[i]; 
    2983     if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue } 
    2984     var collapsed = range$$1.empty(); 
     3073    if (!primary && i == doc.sel.primIndex) { continue } 
     3074    var range = doc.sel.ranges[i] 
     3075    if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue } 
     3076    var collapsed = range.empty() 
    29853077    if (collapsed || cm.options.showCursorWhenSelecting) 
    2986       { drawSelectionCursor(cm, range$$1.head, curFragment); } 
     3078      { drawSelectionCursor(cm, range.head, curFragment) } 
    29873079    if (!collapsed) 
    2988       { drawSelectionRange(cm, range$$1, selFragment); } 
     3080      { drawSelectionRange(cm, range, selFragment) } 
    29893081  } 
    29903082  return result 
     
    29933085// Draws a cursor for the given range 
    29943086function drawSelectionCursor(cm, head, output) { 
    2995   var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); 
    2996  
    2997   var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); 
    2998   cursor.style.left = pos.left + "px"; 
    2999   cursor.style.top = pos.top + "px"; 
    3000   cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; 
     3087  var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine) 
     3088 
     3089  var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")) 
     3090  cursor.style.left = pos.left + "px" 
     3091  cursor.style.top = pos.top + "px" 
     3092  cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px" 
    30013093 
    30023094  if (pos.other) { 
    30033095    // Secondary cursor, shown when on a 'jump' in bi-directional text 
    3004     var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); 
    3005     otherCursor.style.display = ""; 
    3006     otherCursor.style.left = pos.other.left + "px"; 
    3007     otherCursor.style.top = pos.other.top + "px"; 
    3008     otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; 
    3009   } 
    3010 } 
     3096    var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")) 
     3097    otherCursor.style.display = "" 
     3098    otherCursor.style.left = pos.other.left + "px" 
     3099    otherCursor.style.top = pos.other.top + "px" 
     3100    otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px" 
     3101  } 
     3102} 
     3103 
     3104function cmpCoords(a, b) { return a.top - b.top || a.left - b.left } 
    30113105 
    30123106// Draws the given range as a highlighted selection 
    3013 function drawSelectionRange(cm, range$$1, output) { 
    3014   var display = cm.display, doc = cm.doc; 
    3015   var fragment = document.createDocumentFragment(); 
    3016   var padding = paddingH(cm.display), leftSide = padding.left; 
    3017   var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; 
     3107function drawSelectionRange(cm, range, output) { 
     3108  var display = cm.display, doc = cm.doc 
     3109  var fragment = document.createDocumentFragment() 
     3110  var padding = paddingH(cm.display), leftSide = padding.left 
     3111  var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right 
     3112  var docLTR = doc.direction == "ltr" 
    30183113 
    30193114  function add(left, top, width, bottom) { 
    3020     if (top < 0) { top = 0; } 
    3021     top = Math.round(top); 
    3022     bottom = Math.round(bottom); 
    3023     fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n                             top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n                             height: " + (bottom - top) + "px"))); 
     3115    if (top < 0) { top = 0 } 
     3116    top = Math.round(top) 
     3117    bottom = Math.round(bottom) 
     3118    fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n                             top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n                             height: " + (bottom - top) + "px"))) 
    30243119  } 
    30253120 
    30263121  function drawForLine(line, fromArg, toArg) { 
    3027     var lineObj = getLine(doc, line); 
    3028     var lineLen = lineObj.text.length; 
    3029     var start, end; 
     3122    var lineObj = getLine(doc, line) 
     3123    var lineLen = lineObj.text.length 
     3124    var start, end 
    30303125    function coords(ch, bias) { 
    30313126      return charCoords(cm, Pos(line, ch), "div", lineObj, bias) 
    30323127    } 
    30333128 
    3034     iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) { 
    3035       var leftPos = coords(from, "left"), rightPos, left, right; 
    3036       if (from == to) { 
    3037         rightPos = leftPos; 
    3038         left = right = leftPos.left; 
    3039       } else { 
    3040         rightPos = coords(to - 1, "right"); 
    3041         if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } 
    3042         left = leftPos.left; 
    3043         right = rightPos.right; 
     3129    function wrapX(pos, dir, side) { 
     3130      var extent = wrappedLineExtentChar(cm, lineObj, null, pos) 
     3131      var prop = (dir == "ltr") == (side == "after") ? "left" : "right" 
     3132      var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1) 
     3133      return coords(ch, prop)[prop] 
     3134    } 
     3135 
     3136    var order = getOrder(lineObj, doc.direction) 
     3137    iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) { 
     3138      var ltr = dir == "ltr" 
     3139      var fromPos = coords(from, ltr ? "left" : "right") 
     3140      var toPos = coords(to - 1, ltr ? "right" : "left") 
     3141 
     3142      var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen 
     3143      var first = i == 0, last = !order || i == order.length - 1 
     3144      if (toPos.top - fromPos.top <= 3) { // Single line 
     3145        var openLeft = (docLTR ? openStart : openEnd) && first 
     3146        var openRight = (docLTR ? openEnd : openStart) && last 
     3147        var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left 
     3148        var right = openRight ? rightSide : (ltr ? toPos : fromPos).right 
     3149        add(left, fromPos.top, right - left, fromPos.bottom) 
     3150      } else { // Multiple lines 
     3151        var topLeft, topRight, botLeft, botRight 
     3152        if (ltr) { 
     3153          topLeft = docLTR && openStart && first ? leftSide : fromPos.left 
     3154          topRight = docLTR ? rightSide : wrapX(from, dir, "before") 
     3155          botLeft = docLTR ? leftSide : wrapX(to, dir, "after") 
     3156          botRight = docLTR && openEnd && last ? rightSide : toPos.right 
     3157        } else { 
     3158          topLeft = !docLTR ? leftSide : wrapX(from, dir, "before") 
     3159          topRight = !docLTR && openStart && first ? rightSide : fromPos.right 
     3160          botLeft = !docLTR && openEnd && last ? leftSide : toPos.left 
     3161          botRight = !docLTR ? rightSide : wrapX(to, dir, "after") 
     3162        } 
     3163        add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom) 
     3164        if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) } 
     3165        add(botLeft, toPos.top, botRight - botLeft, toPos.bottom) 
    30443166      } 
    3045       if (fromArg == null && from == 0) { left = leftSide; } 
    3046       if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part 
    3047         add(left, leftPos.top, null, leftPos.bottom); 
    3048         left = leftSide; 
    3049         if (leftPos.bottom < rightPos.top) { add(left, leftPos.bottom, null, rightPos.top); } 
    3050       } 
    3051       if (toArg == null && to == lineLen) { right = rightSide; } 
    3052       if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) 
    3053         { start = leftPos; } 
    3054       if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) 
    3055         { end = rightPos; } 
    3056       if (left < leftSide + 1) { left = leftSide; } 
    3057       add(left, rightPos.top, right - left, rightPos.bottom); 
    3058     }); 
     3167 
     3168      if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos } 
     3169      if (cmpCoords(toPos, start) < 0) { start = toPos } 
     3170      if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos } 
     3171      if (cmpCoords(toPos, end) < 0) { end = toPos } 
     3172    }) 
    30593173    return {start: start, end: end} 
    30603174  } 
    30613175 
    3062   var sFrom = range$$1.from(), sTo = range$$1.to(); 
     3176  var sFrom = range.from(), sTo = range.to() 
    30633177  if (sFrom.line == sTo.line) { 
    3064     drawForLine(sFrom.line, sFrom.ch, sTo.ch); 
     3178    drawForLine(sFrom.line, sFrom.ch, sTo.ch) 
    30653179  } else { 
    3066     var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); 
    3067     var singleVLine = visualLine(fromLine) == visualLine(toLine); 
    3068     var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; 
    3069     var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; 
     3180    var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line) 
     3181    var singleVLine = visualLine(fromLine) == visualLine(toLine) 
     3182    var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end 
     3183    var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start 
    30703184    if (singleVLine) { 
    30713185      if (leftEnd.top < rightStart.top - 2) { 
    3072         add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); 
    3073         add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); 
     3186        add(leftEnd.right, leftEnd.top, null, leftEnd.bottom) 
     3187        add(leftSide, rightStart.top, rightStart.left, rightStart.bottom) 
    30743188      } else { 
    3075         add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); 
     3189        add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom) 
    30763190      } 
    30773191    } 
    30783192    if (leftEnd.bottom < rightStart.top) 
    3079       { add(leftSide, leftEnd.bottom, null, rightStart.top); } 
    3080   } 
    3081  
    3082   output.appendChild(fragment); 
     3193      { add(leftSide, leftEnd.bottom, null, rightStart.top) } 
     3194  } 
     3195 
     3196  output.appendChild(fragment) 
    30833197} 
    30843198 
     
    30863200function restartBlink(cm) { 
    30873201  if (!cm.state.focused) { return } 
    3088   var display = cm.display; 
    3089   clearInterval(display.blinker); 
    3090   var on = true; 
    3091   display.cursorDiv.style.visibility = ""; 
     3202  var display = cm.display 
     3203  clearInterval(display.blinker) 
     3204  var on = true 
     3205  display.cursorDiv.style.visibility = "" 
    30923206  if (cm.options.cursorBlinkRate > 0) 
    30933207    { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; }, 
    3094       cm.options.cursorBlinkRate); } 
     3208      cm.options.cursorBlinkRate) } 
    30953209  else if (cm.options.cursorBlinkRate < 0) 
    3096     { display.cursorDiv.style.visibility = "hidden"; } 
     3210    { display.cursorDiv.style.visibility = "hidden" } 
    30973211} 
    30983212 
    30993213function ensureFocus(cm) { 
    3100   if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } 
     3214  if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm) } 
    31013215} 
    31023216 
    31033217function delayBlurEvent(cm) { 
    3104   cm.state.delayingBlurEvent = true; 
     3218  cm.state.delayingBlurEvent = true 
    31053219  setTimeout(function () { if (cm.state.delayingBlurEvent) { 
    3106     cm.state.delayingBlurEvent = false; 
    3107     onBlur(cm); 
    3108   } }, 100); 
     3220    cm.state.delayingBlurEvent = false 
     3221    onBlur(cm) 
     3222  } }, 100) 
    31093223} 
    31103224 
    31113225function onFocus(cm, e) { 
    3112   if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; } 
     3226  if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false } 
    31133227 
    31143228  if (cm.options.readOnly == "nocursor") { return } 
    31153229  if (!cm.state.focused) { 
    3116     signal(cm, "focus", cm, e); 
    3117     cm.state.focused = true; 
    3118     addClass(cm.display.wrapper, "CodeMirror-focused"); 
     3230    signal(cm, "focus", cm, e) 
     3231    cm.state.focused = true 
     3232    addClass(cm.display.wrapper, "CodeMirror-focused") 
    31193233    // This test prevents this from firing when a context 
    31203234    // menu is closed (since the input reset would kill the 
    31213235    // select-all detection hack) 
    31223236    if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { 
    3123       cm.display.input.reset(); 
    3124       if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730 
    3125     } 
    3126     cm.display.input.receivedFocus(); 
    3127   } 
    3128   restartBlink(cm); 
     3237      cm.display.input.reset() 
     3238      if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20) } // Issue #1730 
     3239    } 
     3240    cm.display.input.receivedFocus() 
     3241  } 
     3242  restartBlink(cm) 
    31293243} 
    31303244function onBlur(cm, e) { 
     
    31323246 
    31333247  if (cm.state.focused) { 
    3134     signal(cm, "blur", cm, e); 
    3135     cm.state.focused = false; 
    3136     rmClass(cm.display.wrapper, "CodeMirror-focused"); 
    3137   } 
    3138   clearInterval(cm.display.blinker); 
    3139   setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150); 
     3248    signal(cm, "blur", cm, e) 
     3249    cm.state.focused = false 
     3250    rmClass(cm.display.wrapper, "CodeMirror-focused") 
     3251  } 
     3252  clearInterval(cm.display.blinker) 
     3253  setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false } }, 150) 
     3254} 
     3255 
     3256// Read the actual heights of the rendered lines, and update their 
     3257// stored heights to match. 
     3258function updateHeightsInViewport(cm) { 
     3259  var display = cm.display 
     3260  var prevBottom = display.lineDiv.offsetTop 
     3261  for (var i = 0; i < display.view.length; i++) { 
     3262    var cur = display.view[i], height = (void 0) 
     3263    if (cur.hidden) { continue } 
     3264    if (ie && ie_version < 8) { 
     3265      var bot = cur.node.offsetTop + cur.node.offsetHeight 
     3266      height = bot - prevBottom 
     3267      prevBottom = bot 
     3268    } else { 
     3269      var box = cur.node.getBoundingClientRect() 
     3270      height = box.bottom - box.top 
     3271    } 
     3272    var diff = cur.line.height - height 
     3273    if (height < 2) { height = textHeight(display) } 
     3274    if (diff > .005 || diff < -.005) { 
     3275      updateLineHeight(cur.line, height) 
     3276      updateWidgetHeight(cur.line) 
     3277      if (cur.rest) { for (var j = 0; j < cur.rest.length; j++) 
     3278        { updateWidgetHeight(cur.rest[j]) } } 
     3279    } 
     3280  } 
     3281} 
     3282 
     3283// Read and store the height of line widgets associated with the 
     3284// given line. 
     3285function updateWidgetHeight(line) { 
     3286  if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) { 
     3287    var w = line.widgets[i], parent = w.node.parentNode 
     3288    if (parent) { w.height = parent.offsetHeight } 
     3289  } } 
     3290} 
     3291 
     3292// Compute the lines that are visible in a given viewport (defaults 
     3293// the the current scroll position). viewport may contain top, 
     3294// height, and ensure (see op.scrollToPos) properties. 
     3295function visibleLines(display, doc, viewport) { 
     3296  var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop 
     3297  top = Math.floor(top - paddingTop(display)) 
     3298  var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight 
     3299 
     3300  var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom) 
     3301  // Ensure is a {from: {line, ch}, to: {line, ch}} object, and 
     3302  // forces those lines into the viewport (if possible). 
     3303  if (viewport && viewport.ensure) { 
     3304    var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line 
     3305    if (ensureFrom < from) { 
     3306      from = ensureFrom 
     3307      to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight) 
     3308    } else if (Math.min(ensureTo, doc.lastLine()) >= to) { 
     3309      from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight) 
     3310      to = ensureTo 
     3311    } 
     3312  } 
     3313  return {from: from, to: Math.max(to, from + 1)} 
    31403314} 
    31413315 
     
    31433317// horizontal scrolling. 
    31443318function alignHorizontally(cm) { 
    3145   var display = cm.display, view = display.view; 
     3319  var display = cm.display, view = display.view 
    31463320  if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return } 
    3147   var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; 
    3148   var gutterW = display.gutters.offsetWidth, left = comp + "px"; 
     3321  var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft 
     3322  var gutterW = display.gutters.offsetWidth, left = comp + "px" 
    31493323  for (var i = 0; i < view.length; i++) { if (!view[i].hidden) { 
    31503324    if (cm.options.fixedGutter) { 
    31513325      if (view[i].gutter) 
    3152         { view[i].gutter.style.left = left; } 
     3326        { view[i].gutter.style.left = left } 
    31533327      if (view[i].gutterBackground) 
    3154         { view[i].gutterBackground.style.left = left; } 
    3155     } 
    3156     var align = view[i].alignable; 
     3328        { view[i].gutterBackground.style.left = left } 
     3329    } 
     3330    var align = view[i].alignable 
    31573331    if (align) { for (var j = 0; j < align.length; j++) 
    3158       { align[j].style.left = left; } } 
     3332      { align[j].style.left = left } } 
    31593333  } } 
    31603334  if (cm.options.fixedGutter) 
    3161     { display.gutters.style.left = (comp + gutterW) + "px"; } 
     3335    { display.gutters.style.left = (comp + gutterW) + "px" } 
    31623336} 
    31633337 
     
    31673341function maybeUpdateLineNumberWidth(cm) { 
    31683342  if (!cm.options.lineNumbers) { return false } 
    3169   var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; 
     3343  var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display 
    31703344  if (last.length != display.lineNumChars) { 
    31713345    var test = display.measure.appendChild(elt("div", [elt("div", last)], 
    3172                                                "CodeMirror-linenumber CodeMirror-gutter-elt")); 
    3173     var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; 
    3174     display.lineGutter.style.width = ""; 
    3175     display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; 
    3176     display.lineNumWidth = display.lineNumInnerWidth + padding; 
    3177     display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; 
    3178     display.lineGutter.style.width = display.lineNumWidth + "px"; 
    3179     updateGutterSpace(cm); 
     3346                                               "CodeMirror-linenumber CodeMirror-gutter-elt")) 
     3347    var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW 
     3348    display.lineGutter.style.width = "" 
     3349    display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1 
     3350    display.lineNumWidth = display.lineNumInnerWidth + padding 
     3351    display.lineNumChars = display.lineNumInnerWidth ? last.length : -1 
     3352    display.lineGutter.style.width = display.lineNumWidth + "px" 
     3353    updateGutterSpace(cm) 
    31803354    return true 
    31813355  } 
     
    31833357} 
    31843358 
    3185 // Read the actual heights of the rendered lines, and update their 
    3186 // stored heights to match. 
    3187 function updateHeightsInViewport(cm) { 
    3188   var display = cm.display; 
    3189   var prevBottom = display.lineDiv.offsetTop; 
    3190   for (var i = 0; i < display.view.length; i++) { 
    3191     var cur = display.view[i], height = (void 0); 
    3192     if (cur.hidden) { continue } 
    3193     if (ie && ie_version < 8) { 
    3194       var bot = cur.node.offsetTop + cur.node.offsetHeight; 
    3195       height = bot - prevBottom; 
    3196       prevBottom = bot; 
    3197     } else { 
    3198       var box = cur.node.getBoundingClientRect(); 
    3199       height = box.bottom - box.top; 
    3200     } 
    3201     var diff = cur.line.height - height; 
    3202     if (height < 2) { height = textHeight(display); } 
    3203     if (diff > .001 || diff < -.001) { 
    3204       updateLineHeight(cur.line, height); 
    3205       updateWidgetHeight(cur.line); 
    3206       if (cur.rest) { for (var j = 0; j < cur.rest.length; j++) 
    3207         { updateWidgetHeight(cur.rest[j]); } } 
    3208     } 
    3209   } 
    3210 } 
    3211  
    3212 // Read and store the height of line widgets associated with the 
    3213 // given line. 
    3214 function updateWidgetHeight(line) { 
    3215   if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) 
    3216     { line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight; } } 
    3217 } 
    3218  
    3219 // Compute the lines that are visible in a given viewport (defaults 
    3220 // the the current scroll position). viewport may contain top, 
    3221 // height, and ensure (see op.scrollToPos) properties. 
    3222 function visibleLines(display, doc, viewport) { 
    3223   var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; 
    3224   top = Math.floor(top - paddingTop(display)); 
    3225   var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; 
    3226  
    3227   var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); 
    3228   // Ensure is a {from: {line, ch}, to: {line, ch}} object, and 
    3229   // forces those lines into the viewport (if possible). 
    3230   if (viewport && viewport.ensure) { 
    3231     var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; 
    3232     if (ensureFrom < from) { 
    3233       from = ensureFrom; 
    3234       to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); 
    3235     } else if (Math.min(ensureTo, doc.lastLine()) >= to) { 
    3236       from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); 
    3237       to = ensureTo; 
    3238     } 
    3239   } 
    3240   return {from: from, to: Math.max(to, from + 1)} 
     3359// SCROLLING THINGS INTO VIEW 
     3360 
     3361// If an editor sits on the top or bottom of the window, partially 
     3362// scrolled out of view, this ensures that the cursor is visible. 
     3363function maybeScrollWindow(cm, rect) { 
     3364  if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } 
     3365 
     3366  var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null 
     3367  if (rect.top + box.top < 0) { doScroll = true } 
     3368  else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false } 
     3369  if (doScroll != null && !phantom) { 
     3370    var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n                         top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n                         height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n                         left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;")) 
     3371    cm.display.lineSpace.appendChild(scrollNode) 
     3372    scrollNode.scrollIntoView(doScroll) 
     3373    cm.display.lineSpace.removeChild(scrollNode) 
     3374  } 
     3375} 
     3376 
     3377// Scroll a given position into view (immediately), verifying that 
     3378// it actually became visible (as line heights are accurately 
     3379// measured, the position of something may 'drift' during drawing). 
     3380function scrollPosIntoView(cm, pos, end, margin) { 
     3381  if (margin == null) { margin = 0 } 
     3382  var rect 
     3383  if (!cm.options.lineWrapping && pos == end) { 
     3384    // Set pos and end to the cursor positions around the character pos sticks to 
     3385    // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch 
     3386    // If pos == Pos(_, 0, "before"), pos and end are unchanged 
     3387    pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos 
     3388    end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos 
     3389  } 
     3390  for (var limit = 0; limit < 5; limit++) { 
     3391    var changed = false 
     3392    var coords = cursorCoords(cm, pos) 
     3393    var endCoords = !end || end == pos ? coords : cursorCoords(cm, end) 
     3394    rect = {left: Math.min(coords.left, endCoords.left), 
     3395            top: Math.min(coords.top, endCoords.top) - margin, 
     3396            right: Math.max(coords.left, endCoords.left), 
     3397            bottom: Math.max(coords.bottom, endCoords.bottom) + margin} 
     3398    var scrollPos = calculateScrollPos(cm, rect) 
     3399    var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft 
     3400    if (scrollPos.scrollTop != null) { 
     3401      updateScrollTop(cm, scrollPos.scrollTop) 
     3402      if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true } 
     3403    } 
     3404    if (scrollPos.scrollLeft != null) { 
     3405      setScrollLeft(cm, scrollPos.scrollLeft) 
     3406      if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true } 
     3407    } 
     3408    if (!changed) { break } 
     3409  } 
     3410  return rect 
     3411} 
     3412 
     3413// Scroll a given set of coordinates into view (immediately). 
     3414function scrollIntoView(cm, rect) { 
     3415  var scrollPos = calculateScrollPos(cm, rect) 
     3416  if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop) } 
     3417  if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft) } 
     3418} 
     3419 
     3420// Calculate a new scroll position needed to scroll the given 
     3421// rectangle into view. Returns an object with scrollTop and 
     3422// scrollLeft properties. When these are undefined, the 
     3423// vertical/horizontal position does not need to be adjusted. 
     3424function calculateScrollPos(cm, rect) { 
     3425  var display = cm.display, snapMargin = textHeight(cm.display) 
     3426  if (rect.top < 0) { rect.top = 0 } 
     3427  var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop 
     3428  var screen = displayHeight(cm), result = {} 
     3429  if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen } 
     3430  var docBottom = cm.doc.height + paddingVert(display) 
     3431  var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin 
     3432  if (rect.top < screentop) { 
     3433    result.scrollTop = atTop ? 0 : rect.top 
     3434  } else if (rect.bottom > screentop + screen) { 
     3435    var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen) 
     3436    if (newTop != screentop) { result.scrollTop = newTop } 
     3437  } 
     3438 
     3439  var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft 
     3440  var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0) 
     3441  var tooWide = rect.right - rect.left > screenw 
     3442  if (tooWide) { rect.right = rect.left + screenw } 
     3443  if (rect.left < 10) 
     3444    { result.scrollLeft = 0 } 
     3445  else if (rect.left < screenleft) 
     3446    { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) } 
     3447  else if (rect.right > screenw + screenleft - 3) 
     3448    { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw } 
     3449  return result 
     3450} 
     3451 
     3452// Store a relative adjustment to the scroll position in the current 
     3453// operation (to be applied when the operation finishes). 
     3454function addToScrollTop(cm, top) { 
     3455  if (top == null) { return } 
     3456  resolveScrollToPos(cm) 
     3457  cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top 
     3458} 
     3459 
     3460// Make sure that at the end of the operation the current cursor is 
     3461// shown. 
     3462function ensureCursorVisible(cm) { 
     3463  resolveScrollToPos(cm) 
     3464  var cur = cm.getCursor() 
     3465  cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin} 
     3466} 
     3467 
     3468function scrollToCoords(cm, x, y) { 
     3469  if (x != null || y != null) { resolveScrollToPos(cm) } 
     3470  if (x != null) { cm.curOp.scrollLeft = x } 
     3471  if (y != null) { cm.curOp.scrollTop = y } 
     3472} 
     3473 
     3474function scrollToRange(cm, range) { 
     3475  resolveScrollToPos(cm) 
     3476  cm.curOp.scrollToPos = range 
     3477} 
     3478 
     3479// When an operation has its scrollToPos property set, and another 
     3480// scroll action is applied before the end of the operation, this 
     3481// 'simulates' scrolling that position into view in a cheap way, so 
     3482// that the effect of intermediate scroll commands is not ignored. 
     3483function resolveScrollToPos(cm) { 
     3484  var range = cm.curOp.scrollToPos 
     3485  if (range) { 
     3486    cm.curOp.scrollToPos = null 
     3487    var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to) 
     3488    scrollToCoordsRange(cm, from, to, range.margin) 
     3489  } 
     3490} 
     3491 
     3492function scrollToCoordsRange(cm, from, to, margin) { 
     3493  var sPos = calculateScrollPos(cm, { 
     3494    left: Math.min(from.left, to.left), 
     3495    top: Math.min(from.top, to.top) - margin, 
     3496    right: Math.max(from.right, to.right), 
     3497    bottom: Math.max(from.bottom, to.bottom) + margin 
     3498  }) 
     3499  scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop) 
    32413500} 
    32423501 
    32433502// Sync the scrollable area and scrollbars, ensure the viewport 
    32443503// covers the visible area. 
    3245 function setScrollTop(cm, val) { 
     3504function updateScrollTop(cm, val) { 
    32463505  if (Math.abs(cm.doc.scrollTop - val) < 2) { return } 
    3247   cm.doc.scrollTop = val; 
    3248   if (!gecko) { updateDisplaySimple(cm, {top: val}); } 
    3249   if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; } 
    3250   cm.display.scrollbars.setScrollTop(val); 
    3251   if (gecko) { updateDisplaySimple(cm); } 
    3252   startWorker(cm, 100); 
    3253 } 
     3506  if (!gecko) { updateDisplaySimple(cm, {top: val}) } 
     3507  setScrollTop(cm, val, true) 
     3508  if (gecko) { updateDisplaySimple(cm) } 
     3509  startWorker(cm, 100) 
     3510} 
     3511 
     3512function setScrollTop(cm, val, forceScroll) { 
     3513  val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val) 
     3514  if (cm.display.scroller.scrollTop == val && !forceScroll) { return } 
     3515  cm.doc.scrollTop = val 
     3516  cm.display.scrollbars.setScrollTop(val) 
     3517  if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val } 
     3518} 
     3519 
    32543520// Sync scroller and scrollbar, ensure the gutter elements are 
    32553521// aligned. 
    3256 function setScrollLeft(cm, val, isScroller) { 
    3257   if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) { return } 
    3258   val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); 
    3259   cm.doc.scrollLeft = val; 
    3260   alignHorizontally(cm); 
    3261   if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; } 
    3262   cm.display.scrollbars.setScrollLeft(val); 
    3263 } 
    3264  
    3265 // Since the delta values reported on mouse wheel events are 
    3266 // unstandardized between browsers and even browser versions, and 
    3267 // generally horribly unpredictable, this code starts by measuring 
    3268 // the scroll effect that the first few mouse wheel events have, 
    3269 // and, from that, detects the way it can convert deltas to pixel 
    3270 // offsets afterwards. 
    3271 // 
    3272 // The reason we want to know the amount a wheel event will scroll 
    3273 // is that it gives us a chance to update the display before the 
    3274 // actual scrolling happens, reducing flickering. 
    3275  
    3276 var wheelSamples = 0; 
    3277 var wheelPixelsPerUnit = null; 
    3278 // Fill in a browser-detected starting value on browsers where we 
    3279 // know one. These don't have to be accurate -- the result of them 
    3280 // being wrong would just be a slight flicker on the first wheel 
    3281 // scroll (if it is large enough). 
    3282 if (ie) { wheelPixelsPerUnit = -.53; } 
    3283 else if (gecko) { wheelPixelsPerUnit = 15; } 
    3284 else if (chrome) { wheelPixelsPerUnit = -.7; } 
    3285 else if (safari) { wheelPixelsPerUnit = -1/3; } 
    3286  
    3287 function wheelEventDelta(e) { 
    3288   var dx = e.wheelDeltaX, dy = e.wheelDeltaY; 
    3289   if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; } 
    3290   if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; } 
    3291   else if (dy == null) { dy = e.wheelDelta; } 
    3292   return {x: dx, y: dy} 
    3293 } 
    3294 function wheelEventPixels(e) { 
    3295   var delta = wheelEventDelta(e); 
    3296   delta.x *= wheelPixelsPerUnit; 
    3297   delta.y *= wheelPixelsPerUnit; 
    3298   return delta 
    3299 } 
    3300  
    3301 function onScrollWheel(cm, e) { 
    3302   var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; 
    3303  
    3304   var display = cm.display, scroll = display.scroller; 
    3305   // Quit if there's nothing to scroll here 
    3306   var canScrollX = scroll.scrollWidth > scroll.clientWidth; 
    3307   var canScrollY = scroll.scrollHeight > scroll.clientHeight; 
    3308   if (!(dx && canScrollX || dy && canScrollY)) { return } 
    3309  
    3310   // Webkit browsers on OS X abort momentum scrolls when the target 
    3311   // of the scroll event is removed from the scrollable element. 
    3312   // This hack (see related code in patchDisplay) makes sure the 
    3313   // element is kept around. 
    3314   if (dy && mac && webkit) { 
    3315     outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { 
    3316       for (var i = 0; i < view.length; i++) { 
    3317         if (view[i].node == cur) { 
    3318           cm.display.currentWheelTarget = cur; 
    3319           break outer 
    3320         } 
    3321       } 
    3322     } 
    3323   } 
    3324  
    3325   // On some browsers, horizontal scrolling will cause redraws to 
    3326   // happen before the gutter has been realigned, causing it to 
    3327   // wriggle around in a most unseemly way. When we have an 
    3328   // estimated pixels/delta value, we just handle horizontal 
    3329   // scrolling entirely here. It'll be slightly off from native, but 
    3330   // better than glitching out. 
    3331   if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { 
    3332     if (dy && canScrollY) 
    3333       { setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); } 
    3334     setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); 
    3335     // Only prevent default scrolling if vertical scrolling is 
    3336     // actually possible. Otherwise, it causes vertical scroll 
    3337     // jitter on OSX trackpads when deltaX is small and deltaY 
    3338     // is large (issue #3579) 
    3339     if (!dy || (dy && canScrollY)) 
    3340       { e_preventDefault(e); } 
    3341     display.wheelStartX = null; // Abort measurement, if in progress 
    3342     return 
    3343   } 
    3344  
    3345   // 'Project' the visible viewport to cover the area that is being 
    3346   // scrolled into view (if we know enough to estimate it). 
    3347   if (dy && wheelPixelsPerUnit != null) { 
    3348     var pixels = dy * wheelPixelsPerUnit; 
    3349     var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; 
    3350     if (pixels < 0) { top = Math.max(0, top + pixels - 50); } 
    3351     else { bot = Math.min(cm.doc.height, bot + pixels + 50); } 
    3352     updateDisplaySimple(cm, {top: top, bottom: bot}); 
    3353   } 
    3354  
    3355   if (wheelSamples < 20) { 
    3356     if (display.wheelStartX == null) { 
    3357       display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; 
    3358       display.wheelDX = dx; display.wheelDY = dy; 
    3359       setTimeout(function () { 
    3360         if (display.wheelStartX == null) { return } 
    3361         var movedX = scroll.scrollLeft - display.wheelStartX; 
    3362         var movedY = scroll.scrollTop - display.wheelStartY; 
    3363         var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || 
    3364           (movedX && display.wheelDX && movedX / display.wheelDX); 
    3365         display.wheelStartX = display.wheelStartY = null; 
    3366         if (!sample) { return } 
    3367         wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); 
    3368         ++wheelSamples; 
    3369       }, 200); 
    3370     } else { 
    3371       display.wheelDX += dx; display.wheelDY += dy; 
    3372     } 
    3373   } 
     3522function setScrollLeft(cm, val, isScroller, forceScroll) { 
     3523  val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth) 
     3524  if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return } 
     3525  cm.doc.scrollLeft = val 
     3526  alignHorizontally(cm) 
     3527  if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val } 
     3528  cm.display.scrollbars.setScrollLeft(val) 
    33743529} 
    33753530 
     
    33793534// shot to minimize update/measure roundtrips. 
    33803535function measureForScrollbars(cm) { 
    3381   var d = cm.display, gutterW = d.gutters.offsetWidth; 
    3382   var docH = Math.round(cm.doc.height + paddingVert(cm.display)); 
     3536  var d = cm.display, gutterW = d.gutters.offsetWidth 
     3537  var docH = Math.round(cm.doc.height + paddingVert(cm.display)) 
    33833538  return { 
    33843539    clientHeight: d.scroller.clientHeight, 
     
    33953550 
    33963551var NativeScrollbars = function(place, scroll, cm) { 
    3397   this.cm = cm; 
    3398   var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); 
    3399   var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); 
    3400   place(vert); place(horiz); 
     3552  this.cm = cm 
     3553  var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar") 
     3554  var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar") 
     3555  vert.tabIndex = horiz.tabIndex = -1 
     3556  place(vert); place(horiz) 
    34013557 
    34023558  on(vert, "scroll", function () { 
    3403     if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); } 
    3404   }); 
     3559    if (vert.clientHeight) { scroll(vert.scrollTop, "vertical") } 
     3560  }) 
    34053561  on(horiz, "scroll", function () { 
    3406     if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); } 
    3407   }); 
    3408  
    3409   this.checkedZeroWidth = false; 
     3562    if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal") } 
     3563  }) 
     3564 
     3565  this.checkedZeroWidth = false 
    34103566  // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). 
    3411   if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; } 
     3567  if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px" } 
    34123568}; 
    34133569 
    34143570NativeScrollbars.prototype.update = function (measure) { 
    3415   var needsH = measure.scrollWidth > measure.clientWidth + 1; 
    3416   var needsV = measure.scrollHeight > measure.clientHeight + 1; 
    3417   var sWidth = measure.nativeBarWidth; 
     3571  var needsH = measure.scrollWidth > measure.clientWidth + 1 
     3572  var needsV = measure.scrollHeight > measure.clientHeight + 1 
     3573  var sWidth = measure.nativeBarWidth 
    34183574 
    34193575  if (needsV) { 
    3420     this.vert.style.display = "block"; 
    3421     this.vert.style.bottom = needsH ? sWidth + "px" : "0"; 
    3422     var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); 
     3576    this.vert.style.display = "block" 
     3577    this.vert.style.bottom = needsH ? sWidth + "px" : "0" 
     3578    var totalHeight = measure.viewHeight - (needsH ? sWidth : 0) 
    34233579    // A bug in IE8 can cause this value to be negative, so guard it. 
    34243580    this.vert.firstChild.style.height = 
    3425       Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; 
     3581      Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px" 
    34263582  } else { 
    3427     this.vert.style.display = ""; 
    3428     this.vert.firstChild.style.height = "0"; 
     3583    this.vert.style.display = "" 
     3584    this.vert.firstChild.style.height = "0" 
    34293585  } 
    34303586 
    34313587  if (needsH) { 
    3432     this.horiz.style.display = "block"; 
    3433     this.horiz.style.right = needsV ? sWidth + "px" : "0"; 
    3434     this.horiz.style.left = measure.barLeft + "px"; 
    3435     var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); 
     3588    this.horiz.style.display = "block" 
     3589    this.horiz.style.right = needsV ? sWidth + "px" : "0" 
     3590    this.horiz.style.left = measure.barLeft + "px" 
     3591    var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0) 
    34363592    this.horiz.firstChild.style.width = 
    3437       Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; 
     3593      Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px" 
    34383594  } else { 
    3439     this.horiz.style.display = ""; 
    3440     this.horiz.firstChild.style.width = "0"; 
     3595    this.horiz.style.display = "" 
     3596    this.horiz.firstChild.style.width = "0" 
    34413597  } 
    34423598 
    34433599  if (!this.checkedZeroWidth && measure.clientHeight > 0) { 
    3444     if (sWidth == 0) { this.zeroWidthHack(); } 
    3445     this.checkedZeroWidth = true; 
     3600    if (sWidth == 0) { this.zeroWidthHack() } 
     3601    this.checkedZeroWidth = true 
    34463602  } 
    34473603 
     
    34503606 
    34513607NativeScrollbars.prototype.setScrollLeft = function (pos) { 
    3452   if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; } 
    3453   if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz); } 
     3608  if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos } 
     3609  if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz") } 
    34543610}; 
    34553611 
    34563612NativeScrollbars.prototype.setScrollTop = function (pos) { 
    3457   if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; } 
    3458   if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert); } 
     3613  if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos } 
     3614  if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert") } 
    34593615}; 
    34603616 
    34613617NativeScrollbars.prototype.zeroWidthHack = function () { 
    3462   var w = mac && !mac_geMountainLion ? "12px" : "18px"; 
    3463   this.horiz.style.height = this.vert.style.width = w; 
    3464   this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; 
    3465   this.disableHoriz = new Delayed; 
    3466   this.disableVert = new Delayed; 
     3618  var w = mac && !mac_geMountainLion ? "12px" : "18px" 
     3619  this.horiz.style.height = this.vert.style.width = w 
     3620  this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none" 
     3621  this.disableHoriz = new Delayed 
     3622  this.disableVert = new Delayed 
    34673623}; 
    34683624 
    3469 NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay) { 
    3470   bar.style.pointerEvents = "auto"; 
     3625NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) { 
     3626  bar.style.pointerEvents = "auto" 
    34713627  function maybeDisable() { 
    34723628    // To find out whether the scrollbar is still visible, we 
    34733629    // check whether the element under the pixel in the bottom 
    3474     // left corner of the scrollbar box is the scrollbar box 
     3630    // right corner of the scrollbar box is the scrollbar box 
    34753631    // itself (when the bar is still visible) or its filler child 
    34763632    // (when the bar is hidden). If it is still visible, we keep 
    34773633    // it enabled, if it's hidden, we disable pointer events. 
    3478     var box = bar.getBoundingClientRect(); 
    3479     var elt$$1 = document.elementFromPoint(box.left + 1, box.bottom - 1); 
    3480     if (elt$$1 != bar) { bar.style.pointerEvents = "none"; } 
    3481     else { delay.set(1000, maybeDisable); } 
    3482   } 
    3483   delay.set(1000, maybeDisable); 
     3634    var box = bar.getBoundingClientRect() 
     3635    var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) 
     3636        : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1) 
     3637    if (elt != bar) { bar.style.pointerEvents = "none" } 
     3638    else { delay.set(1000, maybeDisable) } 
     3639  } 
     3640  delay.set(1000, maybeDisable) 
    34843641}; 
    34853642 
    34863643NativeScrollbars.prototype.clear = function () { 
    3487   var parent = this.horiz.parentNode; 
    3488   parent.removeChild(this.horiz); 
    3489   parent.removeChild(this.vert); 
     3644  var parent = this.horiz.parentNode 
     3645  parent.removeChild(this.horiz) 
     3646  parent.removeChild(this.vert) 
    34903647}; 
    34913648 
     
    34983655 
    34993656function updateScrollbars(cm, measure) { 
    3500   if (!measure) { measure = measureForScrollbars(cm); } 
    3501   var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; 
    3502   updateScrollbarsInner(cm, measure); 
     3657  if (!measure) { measure = measureForScrollbars(cm) } 
     3658  var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight 
     3659  updateScrollbarsInner(cm, measure) 
    35033660  for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { 
    35043661    if (startWidth != cm.display.barWidth && cm.options.lineWrapping) 
    3505       { updateHeightsInViewport(cm); } 
    3506     updateScrollbarsInner(cm, measureForScrollbars(cm)); 
    3507     startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; 
     3662      { updateHeightsInViewport(cm) } 
     3663    updateScrollbarsInner(cm, measureForScrollbars(cm)) 
     3664    startWidth = cm.display.barWidth; startHeight = cm.display.barHeight 
    35083665  } 
    35093666} 
     
    35123669// content. 
    35133670function updateScrollbarsInner(cm, measure) { 
    3514   var d = cm.display; 
    3515   var sizes = d.scrollbars.update(measure); 
    3516  
    3517   d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; 
    3518   d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; 
    3519   d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent"; 
     3671  var d = cm.display 
     3672  var sizes = d.scrollbars.update(measure) 
     3673 
     3674  d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px" 
     3675  d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px" 
     3676  d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" 
    35203677 
    35213678  if (sizes.right && sizes.bottom) { 
    3522     d.scrollbarFiller.style.display = "block"; 
    3523     d.scrollbarFiller.style.height = sizes.bottom + "px"; 
    3524     d.scrollbarFiller.style.width = sizes.right + "px"; 
    3525   } else { d.scrollbarFiller.style.display = ""; } 
     3679    d.scrollbarFiller.style.display = "block" 
     3680    d.scrollbarFiller.style.height = sizes.bottom + "px" 
     3681    d.scrollbarFiller.style.width = sizes.right + "px" 
     3682  } else { d.scrollbarFiller.style.display = "" } 
    35263683  if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { 
    3527     d.gutterFiller.style.display = "block"; 
    3528     d.gutterFiller.style.height = sizes.bottom + "px"; 
    3529     d.gutterFiller.style.width = measure.gutterWidth + "px"; 
    3530   } else { d.gutterFiller.style.display = ""; } 
    3531 } 
    3532  
    3533 var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}; 
     3684    d.gutterFiller.style.display = "block" 
     3685    d.gutterFiller.style.height = sizes.bottom + "px" 
     3686    d.gutterFiller.style.width = measure.gutterWidth + "px" 
     3687  } else { d.gutterFiller.style.display = "" } 
     3688} 
     3689 
     3690var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars} 
    35343691 
    35353692function initScrollbars(cm) { 
    35363693  if (cm.display.scrollbars) { 
    3537     cm.display.scrollbars.clear(); 
     3694    cm.display.scrollbars.clear() 
    35383695    if (cm.display.scrollbars.addClass) 
    3539       { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); } 
     3696      { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass) } 
    35403697  } 
    35413698 
    35423699  cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) { 
    3543     cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); 
     3700    cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller) 
    35443701    // Prevent clicks in the scrollbars from killing focus 
    35453702    on(node, "mousedown", function () { 
    3546       if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); } 
    3547     }); 
    3548     node.setAttribute("cm-not-content", "true"); 
     3703      if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0) } 
     3704    }) 
     3705    node.setAttribute("cm-not-content", "true") 
    35493706  }, function (pos, axis) { 
    3550     if (axis == "horizontal") { setScrollLeft(cm, pos); } 
    3551     else { setScrollTop(cm, pos); } 
    3552   }, cm); 
     3707    if (axis == "horizontal") { setScrollLeft(cm, pos) } 
     3708    else { updateScrollTop(cm, pos) } 
     3709  }, cm) 
    35533710  if (cm.display.scrollbars.addClass) 
    3554     { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); } 
    3555 } 
    3556  
    3557 // SCROLLING THINGS INTO VIEW 
    3558  
    3559 // If an editor sits on the top or bottom of the window, partially 
    3560 // scrolled out of view, this ensures that the cursor is visible. 
    3561 function maybeScrollWindow(cm, rect) { 
    3562   if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } 
    3563  
    3564   var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; 
    3565   if (rect.top + box.top < 0) { doScroll = true; } 
    3566   else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; } 
    3567   if (doScroll != null && !phantom) { 
    3568     var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n                         top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n                         height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n                         left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;")); 
    3569     cm.display.lineSpace.appendChild(scrollNode); 
    3570     scrollNode.scrollIntoView(doScroll); 
    3571     cm.display.lineSpace.removeChild(scrollNode); 
    3572   } 
    3573 } 
    3574  
    3575 // Scroll a given position into view (immediately), verifying that 
    3576 // it actually became visible (as line heights are accurately 
    3577 // measured, the position of something may 'drift' during drawing). 
    3578 function scrollPosIntoView(cm, pos, end, margin) { 
    3579   if (margin == null) { margin = 0; } 
    3580   var rect; 
    3581   for (var limit = 0; limit < 5; limit++) { 
    3582     var changed = false; 
    3583     var coords = cursorCoords(cm, pos); 
    3584     var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); 
    3585     rect = {left: Math.min(coords.left, endCoords.left), 
    3586             top: Math.min(coords.top, endCoords.top) - margin, 
    3587             right: Math.max(coords.left, endCoords.left), 
    3588             bottom: Math.max(coords.bottom, endCoords.bottom) + margin}; 
    3589     var scrollPos = calculateScrollPos(cm, rect); 
    3590     var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; 
    3591     if (scrollPos.scrollTop != null) { 
    3592       setScrollTop(cm, scrollPos.scrollTop); 
    3593       if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; } 
    3594     } 
    3595     if (scrollPos.scrollLeft != null) { 
    3596       setScrollLeft(cm, scrollPos.scrollLeft); 
    3597       if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; } 
    3598     } 
    3599     if (!changed) { break } 
    3600   } 
    3601   return rect 
    3602 } 
    3603  
    3604 // Scroll a given set of coordinates into view (immediately). 
    3605 function scrollIntoView(cm, rect) { 
    3606   var scrollPos = calculateScrollPos(cm, rect); 
    3607   if (scrollPos.scrollTop != null) { setScrollTop(cm, scrollPos.scrollTop); } 
    3608   if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); } 
    3609 } 
    3610  
    3611 // Calculate a new scroll position needed to scroll the given 
    3612 // rectangle into view. Returns an object with scrollTop and 
    3613 // scrollLeft properties. When these are undefined, the 
    3614 // vertical/horizontal position does not need to be adjusted. 
    3615 function calculateScrollPos(cm, rect) { 
    3616   var display = cm.display, snapMargin = textHeight(cm.display); 
    3617   if (rect.top < 0) { rect.top = 0; } 
    3618   var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; 
    3619   var screen = displayHeight(cm), result = {}; 
    3620   if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; } 
    3621   var docBottom = cm.doc.height + paddingVert(display); 
    3622   var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin; 
    3623   if (rect.top < screentop) { 
    3624     result.scrollTop = atTop ? 0 : rect.top; 
    3625   } else if (rect.bottom > screentop + screen) { 
    3626     var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen); 
    3627     if (newTop != screentop) { result.scrollTop = newTop; } 
    3628   } 
    3629  
    3630   var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; 
    3631   var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); 
    3632   var tooWide = rect.right - rect.left > screenw; 
    3633   if (tooWide) { rect.right = rect.left + screenw; } 
    3634   if (rect.left < 10) 
    3635     { result.scrollLeft = 0; } 
    3636   else if (rect.left < screenleft) 
    3637     { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)); } 
    3638   else if (rect.right > screenw + screenleft - 3) 
    3639     { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; } 
    3640   return result 
    3641 } 
    3642  
    3643 // Store a relative adjustment to the scroll position in the current 
    3644 // operation (to be applied when the operation finishes). 
    3645 function addToScrollPos(cm, left, top) { 
    3646   if (left != null || top != null) { resolveScrollToPos(cm); } 
    3647   if (left != null) 
    3648     { cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; } 
    3649   if (top != null) 
    3650     { cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; } 
    3651 } 
    3652  
    3653 // Make sure that at the end of the operation the current cursor is 
    3654 // shown. 
    3655 function ensureCursorVisible(cm) { 
    3656   resolveScrollToPos(cm); 
    3657   var cur = cm.getCursor(), from = cur, to = cur; 
    3658   if (!cm.options.lineWrapping) { 
    3659     from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; 
    3660     to = Pos(cur.line, cur.ch + 1); 
    3661   } 
    3662   cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin}; 
    3663 } 
    3664  
    3665 // When an operation has its scrollToPos property set, and another 
    3666 // scroll action is applied before the end of the operation, this 
    3667 // 'simulates' scrolling that position into view in a cheap way, so 
    3668 // that the effect of intermediate scroll commands is not ignored. 
    3669 function resolveScrollToPos(cm) { 
    3670   var range$$1 = cm.curOp.scrollToPos; 
    3671   if (range$$1) { 
    3672     cm.curOp.scrollToPos = null; 
    3673     var from = estimateCoords(cm, range$$1.from), to = estimateCoords(cm, range$$1.to); 
    3674     var sPos = calculateScrollPos(cm, { 
    3675       left: Math.min(from.left, to.left), 
    3676       top: Math.min(from.top, to.top) - range$$1.margin, 
    3677       right: Math.max(from.right, to.right), 
    3678       bottom: Math.max(from.bottom, to.bottom) + range$$1.margin 
    3679     }); 
    3680     cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); 
    3681   } 
     3711    { addClass(cm.display.wrapper, cm.display.scrollbars.addClass) } 
    36823712} 
    36833713 
     
    36883718// combined and executed at once. 
    36893719 
    3690 var nextOpId = 0; 
     3720var nextOpId = 0 
    36913721// Start a new operation. 
    36923722function startOperation(cm) { 
     
    37073737    focus: false, 
    37083738    id: ++nextOpId           // Unique ID 
    3709   }; 
    3710   pushOperation(cm.curOp); 
     3739  } 
     3740  pushOperation(cm.curOp) 
    37113741} 
    37123742 
    37133743// Finish an operation, updating the display and signalling delayed events 
    37143744function endOperation(cm) { 
    3715   var op = cm.curOp; 
     3745  var op = cm.curOp 
    37163746  finishOperation(op, function (group) { 
    37173747    for (var i = 0; i < group.ops.length; i++) 
    3718       { group.ops[i].cm.curOp = null; } 
    3719     endOperations(group); 
    3720   }); 
     3748      { group.ops[i].cm.curOp = null } 
     3749    endOperations(group) 
     3750  }) 
    37213751} 
    37223752 
     
    37243754// that the minimum number of relayouts are required. 
    37253755function endOperations(group) { 
    3726   var ops = group.ops; 
     3756  var ops = group.ops 
    37273757  for (var i = 0; i < ops.length; i++) // Read DOM 
    3728     { endOperation_R1(ops[i]); } 
     3758    { endOperation_R1(ops[i]) } 
    37293759  for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe) 
    3730     { endOperation_W1(ops[i$1]); } 
     3760    { endOperation_W1(ops[i$1]) } 
    37313761  for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM 
    3732     { endOperation_R2(ops[i$2]); } 
     3762    { endOperation_R2(ops[i$2]) } 
    37333763  for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe) 
    3734     { endOperation_W2(ops[i$3]); } 
     3764    { endOperation_W2(ops[i$3]) } 
    37353765  for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM 
    3736     { endOperation_finish(ops[i$4]); } 
     3766    { endOperation_finish(ops[i$4]) } 
    37373767} 
    37383768 
    37393769function endOperation_R1(op) { 
    3740   var cm = op.cm, display = cm.display; 
    3741   maybeClipScrollbars(cm); 
    3742   if (op.updateMaxLine) { findMaxLine(cm); } 
     3770  var cm = op.cm, display = cm.display 
     3771  maybeClipScrollbars(cm) 
     3772  if (op.updateMaxLine) { findMaxLine(cm) } 
    37433773 
    37443774  op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || 
    37453775    op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || 
    37463776                       op.scrollToPos.to.line >= display.viewTo) || 
    3747     display.maxLineChanged && cm.options.lineWrapping; 
     3777    display.maxLineChanged && cm.options.lineWrapping 
    37483778  op.update = op.mustUpdate && 
    3749     new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); 
     3779    new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate) 
    37503780} 
    37513781 
    37523782function endOperation_W1(op) { 
    3753   op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); 
     3783  op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update) 
    37543784} 
    37553785 
    37563786function endOperation_R2(op) { 
    3757   var cm = op.cm, display = cm.display; 
    3758   if (op.updatedDisplay) { updateHeightsInViewport(cm); } 
    3759  
    3760   op.barMeasure = measureForScrollbars(cm); 
     3787  var cm = op.cm, display = cm.display 
     3788  if (op.updatedDisplay) { updateHeightsInViewport(cm) } 
     3789 
     3790  op.barMeasure = measureForScrollbars(cm) 
    37613791 
    37623792  // If the max line changed since it was last measured, measure it, 
     
    37643794  // updateDisplay_W2 will use these properties to do the actual resizing 
    37653795  if (display.maxLineChanged && !cm.options.lineWrapping) { 
    3766     op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; 
    3767     cm.display.sizerWidth = op.adjustWidthTo; 
     3796    op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3 
     3797    cm.display.sizerWidth = op.adjustWidthTo 
    37683798    op.barMeasure.scrollWidth = 
    3769       Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); 
    3770     op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); 
     3799      Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth) 
     3800    op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)) 
    37713801  } 
    37723802 
    37733803  if (op.updatedDisplay || op.selectionChanged) 
    3774     { op.preparedSelection = display.input.prepareSelection(op.focus); } 
     3804    { op.preparedSelection = display.input.prepareSelection() } 
    37753805} 
    37763806 
    37773807function endOperation_W2(op) { 
    3778   var cm = op.cm; 
     3808  var cm = op.cm 
    37793809 
    37803810  if (op.adjustWidthTo != null) { 
    3781     cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; 
     3811    cm.display.sizer.style.minWidth = op.adjustWidthTo + "px" 
    37823812    if (op.maxScrollLeft < cm.doc.scrollLeft) 
    3783