Quran={numSuras:114,numPages:604,numJuzs:30,suraStarts:[],pageStarts:[],juzStarts:[],init:function(){for(var i=1;i<QuranData.Sura.length;i++)
this.suraStarts[i]=this.getSuraStart(i);for(var i=1;i<QuranData.Page.length;i++)
this.pageStarts[i]=this.getPageStart(i);for(var i=1;i<QuranData.Juz.length;i++)
this.juzStarts[i]=this.getJuzStart(i);},getAyaStart:function(sura,aya){aya=aya||1;return this.suraProps(sura).start+(aya-1);},getSuraStart:function(sura){return this.getAyaStart(sura);},getPageStart:function(page){return this.getAyaStart(this.pageProps(page).sura,this.pageProps(page).aya);},getJuzStart:function(juz){return this.getAyaStart(this.juzProps(juz).sura,this.juzProps(juz).aya);},suraProps:function(sura){var s=QuranData.Sura[sura]||[0,7];var data={};var items=['start','ayas','order','rukus','name','tname','ename','type'];for(var i=0;i<items.length;i++)
data[items[i]]=s[i];return data;},pageProps:function(page){var page=QuranData.Page[page]||[1,1];return{sura:page[0],aya:page[1]};},juzProps:function(juz){var juz=QuranData.Juz[juz]||[1,1];return{sura:juz[0],aya:juz[1]};},getPrevAya:function(sura,aya){if(--aya==0)
aya=this.suraProps(--sura).ayas;return{sura:sura,aya:aya};},getNextAya:function(sura,aya){if(++aya>this.suraProps(sura).ayas){aya=1;sura++;}
return{sura:sura,aya:aya};},fixAyaNum:function(sura,aya){return Math.min(Math.max(aya,1),this.suraProps(sura).ayas);},fixSuraNum:function(sura){return Math.min(Math.max(sura,1),this.numSuras);},fixPageNum:function(page){return Math.min(Math.max(page,1),this.numPages);},fixJuzNum:function(juz){return Math.min(Math.max(juz,1),this.numJuzs);},getSuraName:function(sura,nameType){nameType=nameType||'name'
return this.suraProps(sura)[nameType];},getSuraNum:function(suraName,nameType){nameType=nameType||'name'
for(i=1;i<=this.numSuras;i++)
if(this.suraProps(i)[nameType]==suraName)
return i;return 0;},getLineCoords:function(line){var sura=this.binarySearch(this.suraStarts,line);var aya=line-this.suraProps(sura).start+1;return{sura:sura,aya:aya};},getAyaPage:function(sura,aya){return this.binarySearch(this.pageStarts,this.getAyaStart(sura,aya));},getAyaJuz:function(sura,aya){return this.binarySearch(this.juzStarts,this.getAyaStart(sura,aya));},binarySearch:function(theArray,item){var down=0,mid;var up=theArray.length;while(up-down>1){mid=(down+up)>>1;if(theArray[mid]<item)down=mid;else up=mid;}
if(theArray[up]!=item)
return up-1;return up;},getPageItems:function(page){var pageArray=[];var from=this.pageProps(page);var to=this.pageProps(page+1);to=this.getPrevAya(to.sura,to.aya);if(from.sura==to.sura)
pageArray=pageArray.concat(this.getAyaRange(from.sura,from.aya,to.aya));else{pageArray=pageArray.concat(this.getAyaRange(from.sura,from.aya,this.suraProps(from.sura).ayas));for(var i=from.sura+1;i<to.sura;i++)
pageArray=pageArray.concat(this.getAyaRange(i,1,this.suraProps(i).ayas));pageArray=pageArray.concat(this.getAyaRange(to.sura,1,to.aya));}
return pageArray;},getAyaRange:function(sura,fromAya,toAya){var outArray=[];for(i=fromAya;i<=toAya;i++)
outArray.push({sura:sura,aya:i});return outArray;}}
Quran.init();;function AJAX(args)
{
args=args||{};this.method=(args.method=='get')?'get':'post';this.requestTimeout=args.timeout||30;this.xmlResponse=(args.xml==true);this.callBackFunction=null;this.httpRequest=this.createHttpRequest();if(!this.httpRequest)
alert('cannot create httpReauest object...');}
AJAX.prototype.createHttpRequest=function()
{if(window.XMLHttpRequest)
return new XMLHttpRequest();try{return new ActiveXObject("Msxml2.XMLHTTP");}catch(e){try{return new ActiveXObject("Microsoft.XMLHTTP");}catch(e){}}
return null;}
AJAX.prototype.handler=function()
{var response=null;if(this.httpRequest.readyState==4)
{if(this.httpRequest.status==200)
{if(this.xmlResponse)
response=this.httpRequest.responseXML;else
response=this.httpRequest.responseText;}
if(this.callBackFunction!=null)
this.callBackFunction.call(this,response);}}
AJAX.prototype.request=function(destURL,params,procFunc)
{if(!this.httpRequest)
return;var args=this.hashToStr(params);if(this.method=='get')
destURL=destURL+'?'+args;this.callBackFunction=procFunc;this.httpRequest.onreadystatechange=this.handler.bind(this);this.httpRequest.open(this.method,destURL,true);this.httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");this.httpRequest.setRequestHeader("Content-length",args.length);this.httpRequest.setRequestHeader("Connection","close");if(this.httpRequest.timeout)
this.httpRequest.timeout=this.requestTimeout;if(this.httpRequest.overrideMimeType)
this.httpRequest.overrideMimeType(this.xmlResponse?'text/xml':'text/html');this.httpRequest.send(args);}
AJAX.prototype.formRequest=function(destURL,formID,procFunc)
{var args=this.getFormData(formID);this.request(destURL,args,procFunc);}
AJAX.prototype.getFormData=function(formID)
{var theForm=document.getElementById(formID);var str='';for(var e=0;e<theForm.elements.length;e++)
{var name=theForm.elements[e].name;if(!name)continue;args[name]=encodeURIComponent(theForm.elements[e].value);}
return args;}
AJAX.prototype.hashToStr=function(table)
{var args=[];for(var name in table)
args.push(name+'='+table[name]);return args.join('&');}
Function.prototype.bind=function(obj)
{var method=this,temp=function(){return method.apply(obj,arguments);};return temp;};var Cookies={};Cookies.set=function(name,value,expireDays)
{var argv=arguments;var argc=arguments.length;var today=new Date();var expires=(expireDays)?new Date(today.getTime()+expireDays*86400000):null;var path=(argc>3)?argv[3]:'/';var domain=(argc>4)?argv[4]:null;var secure=(argc>5)?argv[5]:false;document.cookie=name+"="+escape(value)+
((expires==null)?"":("; expires="+expires.toGMTString()))+
((path==null)?"":("; path="+path))+
((domain==null)?"":("; domain="+domain))+
((secure==true)?"; secure":"");};Cookies.get=function(name)
{var arg=name+"=";var alen=arg.length;var clen=document.cookie.length;var i=0;var j=0;while(i<clen){j=i+alen;if(document.cookie.substring(i,j)==arg)
return Cookies.getCookieVal(j);i=document.cookie.indexOf(" ",i)+1;if(i==0)
break;}
return null;}
Cookies.getCookieVal=function(offset)
{var endstr=document.cookie.indexOf(";",offset);if(endstr==-1)
endstr=document.cookie.length;return unescape(document.cookie.substring(offset,endstr));}
Cookies.clear=function(name)
{if(Cookies.get(name))
document.cookie=name+"="+"; expires=Thu, 01-Jan-70 00:00:01 GMT";};
var TextTools={matchingRules:[["$HAMZA_SHAPE","$HAMZA_SHAPE"],["$ALEF_MAKSURA","YY"],["$ALEF","[$ALEF$ALEF_MAKSURA$ALEF_WITH_MADDA_ABOVE$ALEF_WITH_HAMZA_ABOVE$ALEF_WITH_HAMZA_BELOW$ALEF_WASLA]"],["[$TEH$MARBUTA]","[$TEH$MARBUTA]"],["$HEH","[$HEH$MARBUTA]"],["$WAW","[$WAW$WAW_WITH_HAMZA_ABOVE$SMALL_WAW]"],["$YEH","[$YEH$ALEF_MAKSURA$YEH_WITH_HAMZA$SMALL_YEH]"],["YY","[$ALEF_MAKSURA$YEH$ALEF]"],[" ","$SPACE"]],wildcardRegs:[["\\.","P"],["\\*","S"],["[?؟]","Q"],["[QS]*S[QS]*","S"],["^\s*[QS]*",""]],wildcards:[["S","$LETTER_HARAKA*"],["Q","$LETTER?"],["P","$LETTER"]],preProcess:[["[$FARSI_YEH$YEH_BARREE]","$YEH"],["[$FARSI_KEHEH$SWASH_KAF]","$KAF"]],init:function()
{for(var i in UGroups)
UGroups[i]=this.regTrans(UGroups[i]);}}
TextTools.regTrans=function(str)
{return str.replace(/\$([A-Z_]+)/g,function(s,i,ofs,all){return UGroups[i]||UChars[i]||'';});}
TextTools.pregReplace=function(fromExp,toExp,str)
{fromExp=new RegExp(this.regTrans(fromExp),'g');toExp=this.regTrans(toExp);return str.replace(fromExp,toExp);}
TextTools.applyRules=function(rules,str)
{
	
	for(var i in rules)
	{
		str=this.pregReplace(rules[i][0],rules[i][1],str);
	}
	return str;
}
TextTools.arabicNumber=function(str)
{var res=String(str).replace(/([0-9])/g,function(s,n,ofs,all){return String.fromCharCode(0x0660+n*1);});return res;}
TextTools.farsiNumber=function(str)
{var res=String(str).replace(/([0-9])/g,function(s,n,ofs,all){return String.fromCharCode(0x06F0+n*1);});return res;}
TextTools.arabicNumberName=function(num)
{var unary=Array('اول','دوم','سوم','چهارم','پنجم','ششم','هفتم','هشتم','نهم','دهم');var decimal=Array('عشر','العشرون','الثلاثون');if(num<1||num>=40)return'';if(num<=10)return unary[num-1];var digit=num%10;var dec=parseInt(num/10);unary[0]='الحادي';var res=(digit>0?unary[digit-1]+(dec>1?' و':' '):'')+decimal[dec-1];return res;}
TextTools.fixText=function(text,args)
{args=args||{};if(args.showSigns)
{text=this.pregReplace(' ([$HIGH_SALA-$HIGH_SEEN])','<span class="sign">&nbsp;$1</span>',text);text=this.pregReplace('([$RUB_EL_HIZB$SAJDAH])',args.ignoreInternalSigns?'':'<span class="internal-sign">$1</span>',text);}
else
text=this.pregReplace('[$HIGH_SALA-$RUB_EL_HIZB$SAJDAH]','',text);if(!args.showSmallAlef)
text=this.pregReplace('$SUPERSCRIPT_ALEF','',text);if(args.font=='me_quran')
text=this.addSpaceTatweel(text);else if(args.type>=10)
{text=this.addSpaceTatweel(text);text=this.removeExtraMeems(text);text=this.pregReplace('($LAM$HARAKA*)$HAMZA($HARAKA*)$ALEF','$1$HAMZA_ABOVE_ALEF$2',text);text=this.pregReplace('$SMALL_YEH($HARAKA*$LETTER)','$TATWEEL$HIGH_YEH$1',text);text=this.pregReplace('$ALEF_MAKSURA($SUPERSCRIPT_ALEF$HARAKA*$LETTER)','$DOTLESS_BEH$1',text);}
text=this.pregReplace('$ALEF$MADDA','$ALEF_WITH_MADDA_ABOVE',text);if(args.font!='me_quran')
text=this.pregReplace('$SHADDA([$KASRA$KASRATAN])','$1$SHADDA',text);return text;}
TextTools.addSpaceTatweel=function(text)
{text=this.pregReplace('($SHADDA|$FATHA)($SUPERSCRIPT_ALEF)','$1$TATWEEL$2',text);text=this.pregReplace('([$HAMZA$DAL-$ZAIN$WAW]$SHADDA?$FATHA)$TATWEEL($SUPERSCRIPT_ALEF)','$1$ZWNJ$2',text);return text;}
TextTools.removeExtraMeems=function(text)
{text=this.pregReplace('([$FATHATAN$DAMMATAN])$LOW_MEEM','$1',text);text=this.pregReplace('($KASRATAN)$HIGH_MEEM','$1',text);return text;}

TextTools.highlight=function(pattern,str)
{
	
//	pattern=new RegExp('('+pattern+')','g');
//	str=str.replace(pattern,'◄$1►');
//	str=str.replace(/◄\s/g,' ◄').replace(/\s►/g,'► ');
//	str=str.replace(/([^\s]*)◄/g,'◄$1').replace(/►([^\s]*)/g,'$1►');
//	while(/◄[^\s]*◄/.test(str))
//		str=str.replace(/(◄[^\s]*)◄/g,'$1').replace(/►([^\s]*►)/g,'$1');
//	str=str.replace(/◄/g,'<span class=highlight>').replace(/►/g,'</span>');
	return str;
}
TextTools.highlightarray=function(pattern,str)
{

	pattern=new RegExp('('+pattern+')','g');
	str=str.replace(pattern,'◄$1►');
	str=str.replace(/◄\s/g,' ◄').replace(/\s►/g,'► ');
	str=str.replace(/([^\s]*)◄/g,'◄$1').replace(/►([^\s]*)/g,'$1►');
	while(/◄[^\s]*◄/.test(str))
		str=str.replace(/(◄[^\s]*)◄/g,'$1').replace(/►([^\s]*►)/g,'$1');
	str=str.replace(/◄/g,'<span class=highlight>').replace(/►/g,'</span>');
	return str;
}

TextTools.enrichPattern=function(pattern,ignoreHaraka)
{
	if(ignoreHaraka)
		pattern=this.pregReplace("$HARAKA",'',pattern);

		pattern=this.regTrans(pattern);
		pattern=this.handleSpaces(pattern);
		pattern=this.applyRules(this.preProcess,pattern);
		pattern=this.applyRules(this.wildcardRegs,pattern);
		pattern=this.pregReplace("(.)","$1$HARAKA*",pattern);
		pattern=this.applyRules(this.matchingRules,pattern);
		pattern=this.applyRules(this.wildcards,pattern);
		return pattern;
}

TextTools.handleSpaces=function(pattern)
{var prev='';if(pattern=='')return pattern;pattern=pattern.replace(/\s+/g,' ');while(pattern!=prev)
{prev=pattern;pattern=pattern.replace(/^(([^"]*"[^"]*")*)([^"\s]*) /g,'$1$3+');}
pattern=pattern.replace(/_/g,' ');pattern=pattern.replace(/"/g,' ');pattern=pattern.replace(/^[+|]+/g,'').replace(/[+|!]+$/g,'');pattern=pattern.replace(/\+*([+|!])\+*/g,'$1');return pattern;}
TextTools.init();var textTools=TextTools;
