
(function(mod){if(typeof exports=="object"&&typeof module=="object")
mod(require("../../lib/codemirror"))
else if(typeof define=="function"&&define.amd)
define(["../../lib/codemirror"],mod)
else
mod(CodeMirror)})(function(CodeMirror){"use strict"
var Pos=CodeMirror.Pos
function regexpFlags(regexp){var flags=regexp.flags
return flags!=null?flags:(regexp.ignoreCase?"i":"")
+(regexp.global?"g":"")
+(regexp.multiline?"m":"")}
function ensureGlobal(regexp){return regexp.global?regexp:new RegExp(regexp.source,regexpFlags(regexp)+"g")}
function maybeMultiline(regexp){return/\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)}
function searchRegexpForward(doc,regexp,start){regexp=ensureGlobal(regexp)
for(var line=start.line,ch=start.ch,last=doc.lastLine();line<=last;line++,ch=0){regexp.lastIndex=ch
var string=doc.getLine(line),match=regexp.exec(string)
if(match)
return{from:Pos(line,match.index),to:Pos(line,match.index+match[0].length),match:match}}}
function searchRegexpForwardMultiline(doc,regexp,start){if(!maybeMultiline(regexp))return searchRegexpForward(doc,regexp,start)
regexp=ensureGlobal(regexp)
var string,chunk=1
for(var line=start.line,last=doc.lastLine();line<=last;){for(var i=0;i<chunk;i++){var curLine=doc.getLine(line++)
string=string==null?curLine:string+"\n"+curLine}
chunk=chunk*2
regexp.lastIndex=start.ch
var match=regexp.exec(string)
if(match){var before=string.slice(0,match.index).split("\n"),inside=match[0].split("\n")
var startLine=start.line+before.length-1,startCh=before[before.length-1].length
return{from:Pos(startLine,startCh),to:Pos(startLine+inside.length-1,inside.length==1?startCh+inside[0].length:inside[inside.length-1].length),match:match}}}}
function lastMatchIn(string,regexp){var cutOff=0,match
for(;;){regexp.lastIndex=cutOff
var newMatch=regexp.exec(string)
if(!newMatch)return match
match=newMatch
cutOff=match.index+(match[0].length||1)
if(cutOff==string.length)return match}}
function searchRegexpBackward(doc,regexp,start){regexp=ensureGlobal(regexp)
for(var line=start.line,ch=start.ch,first=doc.firstLine();line>=first;line--,ch=-1){var string=doc.getLine(line)
if(ch>-1)string=string.slice(0,ch)
var match=lastMatchIn(string,regexp)
if(match)
return{from:Pos(line,match.index),to:Pos(line,match.index+match[0].length),match:match}}}
function searchRegexpBackwardMultiline(doc,regexp,start){regexp=ensureGlobal(regexp)
var string,chunk=1
for(var line=start.line,first=doc.firstLine();line>=first;){for(var i=0;i<chunk;i++){var curLine=doc.getLine(line--)
string=string==null?curLine.slice(0,start.ch):curLine+"\n"+string}
chunk*=2
var match=lastMatchIn(string,regexp)
if(match){var before=string.slice(0,match.index).split("\n"),inside=match[0].split("\n")
var startLine=line+before.length,startCh=before[before.length-1].length
return{from:Pos(startLine,startCh),to:Pos(startLine+inside.length-1,inside.length==1?startCh+inside[0].length:inside[inside.length-1].length),match:match}}}}
var doFold,noFold
if(String.prototype.normalize){doFold=function(str){return str.normalize("NFD").toLowerCase()}
noFold=function(str){return str.normalize("NFD")}}else{doFold=function(str){return str.toLowerCase()}
noFold=function(str){return str}}
function adjustPos(orig,folded,pos){if(orig.length==folded.length)return pos
for(var pos1=Math.min(pos,orig.length);;){var len1=orig.slice(0,pos1).toLowerCase().length
if(len1<pos)++pos1
else if(len1>pos)--pos1
else return pos1}}
function searchStringForward(doc,query,start,caseFold){if(!query.length)return null
var fold=caseFold?doFold:noFold
var lines=fold(query).split(/\r|\n\r?/)
search:for(var line=start.line,ch=start.ch,last=doc.lastLine()+1-lines.length;line<=last;line++,ch=0){var orig=doc.getLine(line).slice(ch),string=fold(orig)
if(lines.length==1){var found=string.indexOf(lines[0])
if(found==-1)continue search
var start=adjustPos(orig,string,found)+ch
return{from:Pos(line,adjustPos(orig,string,found)+ch),to:Pos(line,adjustPos(orig,string,found+lines[0].length)+ch)}}else{var cutFrom=string.length-lines[0].length
if(string.slice(cutFrom)!=lines[0])continue search
for(var i=1;i<lines.length-1;i++)
if(fold(doc.getLine(line+i))!=lines[i])continue search
var end=doc.getLine(line+lines.length-1),endString=fold(end),lastLine=lines[lines.length-1]
if(end.slice(0,lastLine.length)!=lastLine)continue search
return{from:Pos(line,adjustPos(orig,string,cutFrom)+ch),to:Pos(line+lines.length-1,adjustPos(end,endString,lastLine.length))}}}}
function searchStringBackward(doc,query,start,caseFold){if(!query.length)return null
var fold=caseFold?doFold:noFold
var lines=fold(query).split(/\r|\n\r?/)
search:for(var line=start.line,ch=start.ch,first=doc.firstLine()-1+lines.length;line>=first;line--,ch=-1){var orig=doc.getLine(line)
if(ch>-1)orig=orig.slice(0,ch)
var string=fold(orig)
if(lines.length==1){var found=string.lastIndexOf(lines[0])
if(found==-1)continue search
return{from:Pos(line,adjustPos(orig,string,found)),to:Pos(line,adjustPos(orig,string,found+lines[0].length))}}else{var lastLine=lines[lines.length-1]
if(string.slice(0,lastLine.length)!=lastLine)continue search
for(var i=1,start=line-lines.length+1;i<lines.length-1;i++)
if(fold(doc.getLine(start+i))!=lines[i])continue search
var top=doc.getLine(line+1-lines.length),topString=fold(top)
if(topString.slice(topString.length-lines[0].length)!=lines[0])continue search
return{from:Pos(line+1-lines.length,adjustPos(top,topString,top.length-lines[0].length)),to:Pos(line,adjustPos(orig,string,lastLine.length))}}}}
function SearchCursor(doc,query,pos,options){this.atOccurrence=false
this.doc=doc
pos=pos?doc.clipPos(pos):Pos(0,0)
this.pos={from:pos,to:pos}
var caseFold
if(typeof options=="object"){caseFold=options.caseFold}else{caseFold=options
options=null}
if(typeof query=="string"){if(caseFold==null)caseFold=false
this.matches=function(reverse,pos){return(reverse?searchStringBackward:searchStringForward)(doc,query,pos,caseFold)}}else{query=ensureGlobal(query)
if(!options||options.multiline!==false)
this.matches=function(reverse,pos){return(reverse?searchRegexpBackwardMultiline:searchRegexpForwardMultiline)(doc,query,pos)}
else
this.matches=function(reverse,pos){return(reverse?searchRegexpBackward:searchRegexpForward)(doc,query,pos)}}}
SearchCursor.prototype={findNext:function(){return this.find(false)},findPrevious:function(){return this.find(true)},find:function(reverse){var result=this.matches(reverse,this.doc.clipPos(reverse?this.pos.from:this.pos.to))
while(result&&CodeMirror.cmpPos(result.from,result.to)==0){if(reverse){if(result.from.ch)result.from=Pos(result.from.line,result.from.ch-1)
else if(result.from.line==this.doc.firstLine())result=null
else result=this.matches(reverse,this.doc.clipPos(Pos(result.from.line-1)))}else{if(result.to.ch<this.doc.getLine(result.to.line).length)result.to=Pos(result.to.line,result.to.ch+1)
else if(result.to.line==this.doc.lastLine())result=null
else result=this.matches(reverse,Pos(result.to.line+1,0))}}
if(result){this.pos=result
this.atOccurrence=true
return this.pos.match||true}else{var end=Pos(reverse?this.doc.firstLine():this.doc.lastLine()+1,0)
this.pos={from:end,to:end}
return this.atOccurrence=false}},from:function(){if(this.atOccurrence)return this.pos.from},to:function(){if(this.atOccurrence)return this.pos.to},replace:function(newText,origin){if(!this.atOccurrence)return
var lines=CodeMirror.splitLines(newText)
this.doc.replaceRange(lines,this.pos.from,this.pos.to,origin)
this.pos.to=Pos(this.pos.from.line+lines.length-1,lines[lines.length-1].length+(lines.length==1?this.pos.from.ch:0))}}
CodeMirror.defineExtension("getSearchCursor",function(query,pos,caseFold){return new SearchCursor(this.doc,query,pos,caseFold)})
CodeMirror.defineDocExtension("getSearchCursor",function(query,pos,caseFold){return new SearchCursor(this,query,pos,caseFold)})
CodeMirror.defineExtension("selectMatches",function(query,caseFold){var ranges=[]
var cur=this.getSearchCursor(query,this.getCursor("from"),caseFold)
while(cur.findNext()){if(CodeMirror.cmpPos(cur.to(),this.getCursor("to"))>0)break
ranges.push({anchor:cur.from(),head:cur.to()})}
if(ranges.length)
this.setSelections(ranges,0)})});