/*Created by HPWizard.com*/


var FINAL = 0;/*writing final equation*/
var FUNCTION = 1;/*writing equation after a function was solved*/
var cleanEq="";/*the 'clean' equations presented in the output text area*/
var previousEq="";/*the previous equation that was written*/

/*The function hideCalculator() show and hide the input text area*/

function hideCalculator()
{
	if(document.getElementById("input-area").style.display == "none")
	{	/*show input text area*/
		document.getElementById("input-area").style.display ="inline";
		document.getElementById("output-area").style.display ="block";
		document.getElementById("output-area").innerHTML=""; /*reset output area*/
		document.getElementById("input-area").focus();
	}
	else
	{	/*hide input text area*/
		document.getElementById("input-area").style.display ="none";
		document.getElementById("output-area").style.display ="none";
	}
}
/*The function check(e) checks if the 'Enter' key was pressed and run the function calculate() if so*/
function check(e)
{
	if(window.event) // IE
	{
		if(e.keyCode==13){calculate();}
	}
	else if(e.which) // Netscape/Firefox/Opera
	{
		if(e.which==13){calculate();}
	}
}
/*The function checkChar(e) make sure only accepted characters or keys can be used in the input text area*/
function checkChar(e)
{	
	var keynum;
	var keychar;
	var numcheck;
/*record key code:*/
	if(window.event) // IE
	{
		keynum = e.keyCode;
	}
	else if(e.which) // Netscape/Firefox/Opera
	{
		keynum = e.which;
	}
	
	switch(keynum)
	{/*key codes for 'left arrow', 'right arrow', 'home' and 'end' keys*/
		case 35:return true;
		case 36:return true;
		case 37:return true;
		case 39:return true;
	}

	keychar = String.fromCharCode(keynum);/*get character from key code*/
	numcheck = /[\x2a\x2b\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x45\x47\x48\x4c\x4e\x4f\x50\x53\x54\x61\x62\x63\x65\x67\x68\x6c\x6e\x6f\x70\x73\x74\xa0\xab\xbb\x08\x7f]/;/*set list of accepted characters*/
	return numcheck.test(keychar);/*compare character with list of accepted characters*/
}
/*The function calculate() is called when the 'enter' key is pressed*/
function calculate()
{
	/*get the equation:*/
	var equation = document.getElementById("input-area").value;
	/*put it to lower case:*/
	equation = equation.toLowerCase();

	if(equation=="help"){window.open("calculator.html","_self");}/*'help' was typed --> open the help page*/
	else
	{
		cleanEq="";/*initialize the clean equation*/
		equation = fillEq(equation);/*look for and add missing parenthesis and implied multiplications*/
		writeCleanEq(equation, FUNCTION);/*write the first clean equation as read by the program*/
		var answer=solveFunc(equation);/*solve the equation*/
		
		document.getElementById("output-area").innerHTML = writeHTML(cleanEq,answer);/*write the final equation and put it in the output text area*/
	}
}
/*the function writeHTML(eq,answer) adds the 'answer' at the end of the clean equations 'eq'*/
function writeHTML(eq,answer)
{
	var temp = answer;
	var sign = String.fromCharCode(8734);/*infinity sign*/
	temp = String(temp).replace(/Infinity/gi,sign);/*replace all words 'Infinity' by the sign*/
	temp = String(temp).replace(/NaNty/gi,"InfiniNaN");/*replace all 'NaNty' by InfiniNaN*/
	temp = String(temp).replace(/NaNNaN/gi,"InfiniNaN");/*replace all 'NaNNaN' by InfiniNaN*/
	temp = String(temp).replace(/NaNaN/gi,"InfiniNaN");/*replace all 'NaNaN' by InfiniNaN*/
	temp = String(temp).replace(/e-/g,"e/");/*replace all 'e-' to 'e/' temporarely*/
	sign = String.fromCharCode(8722) + " ";/*set the minus sign (with spaces)*/
	temp = String(temp).replace(/-/g,sign);/*replace all minus signs*/
	temp = String(temp).replace(/e\//g,"E-");/*replace all 'e/' (i.e. 'e-') to 'E-' (such that there is no space after the '-')*/
	temp = String(temp).replace(/e\+/g,"E");/*replace all 'e+' to 'E'*/
	
	return eq + "<b>" + temp + "</b>";/*write the answer in bold at the end of the clean equations*/
}
/*the function writeCleanEq(eq,flag) writes the clean equations base on the solved equation 'eq' and according to the way it is flagged by 'flag'*/
function writeCleanEq(eq, flag)
{
	var newEq=eq;/*new eqaution to be added to the clean equations*/
	var sign="";/*sign that will be used in the clean equation*/

	if(flag==FUNCTION)
	{/*not the last equation to be solved*/
		newEq = String(newEq).replace(/«/g,"(");/*replace all opening parenthesis*/
		newEq = String(newEq).replace(/»/g,")");/*replace all closing parenthesis*/
		sign = String.fromCharCode(8734);/*set sign to 'infinity' sign*/
		newEq = String(newEq).replace(/Infinity/gi,sign);/*replace all words 'Infinity' to the sign*/
		/*replace all forms of 'InfiniNaN' with uppercase such that the 'n' will not be interpreted as Euler's number:*/
		newEq = String(newEq).replace(/InfiniNaN/gi,"INFININAN");
		newEq = String(newEq).replace(/NaNty/gi,"INFININAN");
		newEq = String(newEq).replace(/NaNNaN/gi,"INFININAN");
		newEq = String(newEq).replace(/NaNaN/gi,"INFININAN");
		/*replace all exponents, ASIN, ACOS, ATAN, SIN, COS, TAN:*/
		newEq = String(newEq).replace(/\*\*/g,"^");
		newEq = String(newEq).replace(/as/g,"ASIN");
		newEq = String(newEq).replace(/ac/g,"ACOS");
		newEq = String(newEq).replace(/at/g,"ATAN");
		newEq = String(newEq).replace(/s/g,"SIN");
		newEq = String(newEq).replace(/c/g,"COS");
		newEq = String(newEq).replace(/t/g,"TAN");
		
		sign = " " + String.fromCharCode(247) + " "; /*set the 'divide' sign*/
		newEq = String(newEq).replace(/\//g,sign);/*replace all 'divide' signs */
		/*replace all log:*/
		newEq = String(newEq).replace(/lb/g,"LOG<sub>2</sub> ");
		newEq = String(newEq).replace(/lg/g,"LOG<sub>10</sub> ");
		newEq = String(newEq).replace(/log/g,"LOG<sub>10</sub> ");
		newEq = String(newEq).replace(/ln/g,"LN ");
		
		sign = " " + String.fromCharCode(215) + " ";/*set the 'times' sign*/
		newEq = String(newEq).replace(/\*/g,sign);/*replace all 'times' signs*/
		newEq = String(newEq).replace(/e-/g,"e/");/*replace all 'e-' to 'e/' temporarely*/
		sign = " " + String.fromCharCode(8722) + " ";/*set the minus sign (with spaces)*/
		newEq = String(newEq).replace(/-/g,sign);/*replace all minus signs*/
		newEq = String(newEq).replace(/e\//g,"E-");/*replace all 'e/' (i.e. 'e-') to 'E-' (such that there is no space between the 'E' and '-')*/
		newEq = String(newEq).replace(/e\+/g,"e/");/*replace all 'e+' to 'e/' temporarely*/
		newEq = String(newEq).replace(/\+/g," + ");/*replace all plus signs (with spaces)*/
		newEq = String(newEq).replace(/e\//g,"E");/*replace all 'e/' (i.e. 'e+') to 'E'*/
		sign = " " + String.fromCharCode(960) + " ";/*set sign to pi*/
		newEq = String(newEq).replace(/p/g,sign);/*replace all pi to the sign*/
		newEq = String(newEq).replace(/e/g,"E");/*replace all 'e' to 'E'*/
		newEq = String(newEq).replace(/n/g,"e");/*replace all 'n' (Euler'number) to 'e'*/
		newEq = String(newEq).replace(/InfiniNaN/gi,"InfiniNaN");/*Set all 'INFININAN' (case insensitive) to 'InfiniNaN'*/
		
		if(newEq != previousEq)
		{/*if the new equation is not the same as the previous one, write it*/
			if(isNaN(Number(newEq)))/*the equation is a string or NaN*/
			{
				if(newEq=="InfiniNaN"  || newEq=="NaNaN" || newEq=="NaNNaN" || newEq=="NaN"){}/*The equation is NaN, don't write (it will be the final answer)*/
				else{cleanEq = cleanEq + newEq + " = <br>";}/*add the new equation to the previously solved*/
			}
		}
		
		previousEq = newEq;/*set the new equations as the previous equation*/
	}
	else if(flag==FINAL)
	{/*last equation that was solved; similar to FUNCTION (less function name) except where noted*/
		newEq = String(newEq).replace(/«/g,"(");
		newEq = String(newEq).replace(/»/g,")");
		sign = String.fromCharCode(8734);
		newEq = String(newEq).replace(/Infinity/gi,sign);
		newEq = String(newEq).replace(/NaNty/gi,"InfiniNaN");
		newEq = String(newEq).replace(/NaNNaN/gi,"InfiniNaN");
		newEq = String(newEq).replace(/NaNaN/gi,"InfiniNaN");
		newEq = String(newEq).replace(/e-/g,"e/");
		sign = " " + String.fromCharCode(8722) + " ";
		newEq = String(newEq).replace(/\+-/g,sign);/*replace all '+-' to sign */
		newEq = String(newEq).replace(/-/g,sign);
		newEq = String(newEq).replace(/e\//g,"E-");
		newEq = String(newEq).replace(/e\+/g,"e/");
		newEq = String(newEq).replace(/\+/g," + ");
		newEq = String(newEq).replace(/e\//g,"E");
		newEq = String(newEq).replace(/e/g,"E");
		
		if(newEq != previousEq)
		{	
			if(isNaN(Number(newEq)))
			{
				if(newEq=="InfiniNaN"  || newEq=="NaNaN" || newEq=="NaNNaN" || newEq=="NaN"){}
				else{cleanEq = cleanEq + newEq + " = <br>";}
			}
		}
		
		previousEq = newEq;
	}
}
/*the function solveFunc(eq) reads and solves the equation 'eq'*/
function solveFunc(eq)
{
	var pos;/*index position*/
	var parPos;/*position of parenthesis*/
	var check=0;/*previous index position*/
	var openPar= new Array();/*array of opening parenthesis position*/
	var closePar=new Array();/*array of closing parenthesis position*/
	var min;/*smallest difference between closing and opening parenthesis*/
	var temp;/*difference between closing and opening parenthesis*/
	var answer;/*answer from the equation within parenthesis*/
	var notReady = false;/*not ready to be solved*/
	var counter = 0;
	
	openPar[0]=0;/*initialize first open parenthesis position*/
	
	try{
	while(openPar[0]!=-1)/*solve functions until there is no more equations within parenthesis*/
	{
		/*solve the function 'p':*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;/*record previous index position*/
			pos = eq.indexOf("p",pos);/*find next index position*/
			if (pos!=-1){eq = solvePI(eq);pos=0;}/*if found, solve function and reset pos to 0*/
			else
			{
				pos=1e100;/*set pos high such that for loop will end*/
				if(check!=0){writeCleanEq(eq,FUNCTION);}/*if at least one function was found, write the clean equation*/
			}
		}
		check=0;/*reset check to 0*/
		
		/*solve the function 'n': (same as function 'p' except where noted)*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("n",pos);
			if (pos!=-1)
			{
				if(eq.charAt(pos-1)!="l" && eq.charAt(pos-1)!="i" && eq.charAt(pos-1)!="I"){eq = solveE(eq);pos=0;}/*the character before 'n' is 'l' (function'ln') or 'i' ('I') ('InfiniNaN' 'Infinity')*/
			}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function '**': (same as function 'p' except where noted)*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("**",pos);
			parPos=eq.indexOf("**«",check);/*check if there is an exponent who is an equation (between parenthesis)*/
			if (pos!=-1 && parPos!=pos)/*if '**' exists and it is not followed by a parenthesis*/
			{
				notReady=false;/*ready to be solved (since the exponent is a number)*/
				
				if(eq.charAt(pos-1)=="»")/*check if the base number is an equation*/
				{
					for(i=pos-2;i>=0;i--)
					{
						if(eq.charAt(i)=="«")/*find the opening parenthesis of the base number*/
						{
							if(isNaN(eq.substring(i+1,pos-1))){notReady=true;}/*if it is not a number set to not ready to be solved*/
							else{break;}/*else continue*/
						}
					}
				}
				if(notReady){break;}/*if no ready to be solved, break*/
				eq = solveEXPONENT(eq,pos);/*solve function*/
				pos=0;
			}
			else if(pos!=-1){}/*if there is no function to be solved, do nothing*/
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'as': (same as function 'p' except where noted)*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("as",pos);
			parPos=eq.indexOf("as«",check);/*check if there is an argument for 'as' who is an equation (between parenthesis)*/
			if (pos!=-1 && parPos!=pos){eq = solveASIN(eq,pos);pos=0;}/*if 'as' exists and it is not followed by a parenthesis, solve the function and reset pos to 0*/
			else if(pos!=-1){}/*if there is no function to be solved, do nothing*/
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'ac': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("ac",pos);
			parPos=eq.indexOf("ac«",check);
			if (pos!=-1 && parPos!=pos){eq = solveACOS(eq,pos);pos=0;}
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'at': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("at",pos);
			parPos=eq.indexOf("at«",check);
			if (pos!=-1 && parPos!=pos){eq = solveATAN(eq,pos);pos=0;}
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 's': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("s",pos);
			parPos=eq.indexOf("s«",check);
			if (pos!=-1 && parPos!=pos){eq = solveSIN(eq,pos);pos=0;}
			else if(pos!=-1){} 
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'c': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("c",pos);
			parPos=eq.indexOf("c«",check);
			if (pos!=-1 && parPos!=pos){eq = solveCOS(eq,pos);pos=0;}
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 't': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("t",pos);
			parPos=eq.indexOf("t«",check);
			if (pos!=-1 && parPos!=pos){eq = solveTAN(eq,pos);pos=0;}
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'log': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("log",pos);
			parPos=eq.indexOf("log«",check);
			if (pos!=-1 && parPos!=pos){eq = solveLOG(eq,pos);pos=0;} 
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'lg': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("lg",pos);
			parPos=eq.indexOf("lg«",check);
			if (pos!=-1 && parPos!=pos){eq = solveLG(eq,pos);pos=0;} 
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'lb': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("lb",pos);
			parPos=eq.indexOf("lb«",check);
			if (pos!=-1 && parPos!=pos){eq = solveLB(eq,pos);pos=0;}
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve the function 'ln': (same as function 'as')*/
		
		for (pos=0;pos<eq.length;pos++)
		{
			check=pos;
			pos = eq.indexOf("ln",pos);
			parPos=eq.indexOf("ln«",check);
			if (pos!=-1 && parPos!=pos){eq = solveLN(eq,pos);pos=0;} 
			else if(pos!=-1){}
			else
			{
				pos=1e100;
				if(check!=0){writeCleanEq(eq,FUNCTION);}
			}
		}
		check=0;
		
		/*solve equations in parenthesis:*/
		
		openPar=findOpenPar(eq);/*fill the array for the opening parenthesis*/
		closePar=findClosePar(eq);/*fill the array for the closing parenthesis*/
		/*initialize variables:*/
		min=0;
		temp=0;
		
		if(openPar[0]!=-1)/*if there are parenthesis*/
		{
			min = closePar[closePar.length-1]-openPar[0];/*initialize the smallest difference in index position between last closing and first opening parenthesis*/
			/*set the first and last index for the equation to be solved:*/
			firstIndex=openPar[0];
			lastIndex=closePar[closePar.length-1];
			
			notReady=false;/*equation not ready to be solved*/
			
			/*find most inner matching opening and closing parenthesis*/
			for(i=0;i<openPar.length;i++)
			{
				for(j=0;j<closePar.length;j++)
				{
					if(eq.substring(closePar[j]+1,closePar[j]+3)=="**" && !isNaN(eq.substring(openPar[i]+1,closePar[j]))){notReady=true;}/*if closing parenthesis is followed by exponent (solved by exponent function) and is not a number (hence a string or equation) --> not ready to be solved (must be a number inside for the exponent function)*/
					else
					{
						temp = closePar[j]-openPar[i];/*find difference between closing and opening parenthesis*/
						if(temp<min && temp>=0){min=temp; firstIndex=openPar[i]; lastIndex=closePar[j];}/*if difference smaller than 'min', store it and record first and last index*/
						notReady=false;/*ready to be solved*/
					}
				}
			}
			if(!notReady)/*ready to be solved*/
			{
				answer = solveAllMult(eq.substring(firstIndex+1,lastIndex), FUNCTION);/*solve all multiplication and addition*/
				
				if(eq.substring(lastIndex+1,lastIndex+3)!="**"){eq = eq.replace(eq.substring(firstIndex,lastIndex+1),answer);}/*if the equation was the base number for the exponent function, keep the parenthesis (such that the exponent function knows if it is a negative number)*/
				else{eq = eq.replace(eq.substring(firstIndex+1,lastIndex),answer);}/*replace the equation with the answer*/
				writeCleanEq(eq,FUNCTION);/*write the clean equation*/
			}
		}
		counter++;
		if(counter==100){throw "internal"}
	}

	return solveAllMult(eq,FINAL);/*solve all multiplication and addition (FINAL)*/

	}catch(err){if(err="internal"){return "internal error";} else {return "error";}}
}
/*the function solveLOG(eq,pos) solve the log10 at index position 'pos' in the equation 'eq'*/
function solveLOG(eq,pos)
{
	var number;/*argument of function*/
	var lastIndex;/*last index of of number*/
	var charValue;/*character studied*/
	/*find last index:*/
	for(i=pos+3;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{/*charValue is not a number*/
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") /*charValue is part of multiplier 'E+' or 'E-'*/ || (charValue == "-" && eq.charAt(i-1) == "g")/*number is negative*/){}/*do nothing and continue search*/
			else
			{/*last index found*/
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+3,i);
				lastIndex = i;
				i=1e100;/*get out of for loop*/
			}
		}
	}
	/*do the math:*/
	number = Math.log(number)/Math.log(10);
	
	return eq.replace(eq.substring(pos,lastIndex),number);/*replace function with answer in equation*/
}
/*the function solveLG(eq,pos) solve the log10 at index position 'pos' in the equation 'eq'*/
function solveLG(eq,pos)
{/*similar as solveLOG(eq,pos) except for beginning of for loop and number substring*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+2;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "g")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+2,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.log(number)/Math.log(10);
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveLB(eq,pos) solve the log2 at index position 'pos' in the equation 'eq'*/
function solveLB(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+2;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "b")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+2,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.log(number)/Math.log(2);
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveLN(eq,pos) solve the natural log at index position 'pos' in the equation 'eq'*/
function solveLN(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+2;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "n")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+2,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.log(number);
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveTAN(eq,pos) solve the tangent (in degrees) at index position 'pos' in the equation 'eq'*/
function solveTAN(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+1;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "t")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+1,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.tan(number*Math.PI/180);
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveCOS(eq,pos) solve the cosine (in degrees) at index position 'pos' in the equation 'eq'*/
function solveCOS(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+1;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "c")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+1,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.cos(number*Math.PI/180);
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveSIN(eq,pos) solve the sine (in degrees) at index position 'pos' in the equation 'eq'*/
function solveSIN(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+1;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "s")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+1,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.sin(number*Math.PI/180);
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveATAN(eq,pos) solve the arctangent (in degrees) at index position 'pos' in the equation 'eq'*/
function solveATAN(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+2;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "t")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+2,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.atan(number)*180/Math.PI;
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveACOS(eq,pos) solve the arccosine (in degrees) at index position 'pos' in the equation 'eq'*/
function solveACOS(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+2;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "c")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+2,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.acos(number)*180/Math.PI;
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solveASIN(eq,pos) solve the arcsine (in degrees) at index position 'pos' in the equation 'eq'*/
function solveASIN(eq,pos)
{/*similar as solveLOG(eq,pos)*/
	var number;
	var lastIndex;
	var charValue;

	for(i=pos+2;i<eq.length;i++)
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "s")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				number = eq.substring(pos+2,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}

	number = Math.asin(number)*180/Math.PI;
	
	return eq.replace(eq.substring(pos,lastIndex),number);
}
/*the function solvePI(eq) replaces all 'p' with the value of pi in the equation 'eq'*/
function solvePI(eq){return eq.replace(/p/g,Math.PI);}
/*the function solveE(eq) replaces all 'n' with the value of Euler's number in the equation 'eq'*/
function solveE(eq)
{
	var tempEq = eq.replace(/ln/g,"LN");/*change 'ln' to 'LN' such that the 'n' is not changed*/
	tempEq = tempEq.replace(/n/g,Math.E);
	return tempEq.replace(/LN/g,"ln");/*change 'LN' back to 'ln'*/
}
/*the function solveEXPONENT(eq,pos) solves a number raise to a power in equation 'eq' at index position 'pos'*/
function solveEXPONENT(eq,pos)
{
	var number;/*number to be raised*/
	var exponent;/*exponent*/
	var firstIndex;
	var lastIndex;
	var charValue;

	for(i=pos-1;i>=0;i--)/*look for first index of number (similar to solveLOG(eq,pos) except where noted)*/
	{
		charValue=eq.charAt(i);
		
		if(i == 0 || charValue=="«" || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "n"  || charValue == "g" || charValue == "b" || charValue == "s" || charValue == "c" || charValue == "t")
		{
			if(i==0 && eq.charAt(pos-1)=="»"){number = eq.substring(i+1,pos-1); firstIndex = i;}/*'«' found at first index of equation*/
			else if(charValue=="-" && eq.charAt(i-1)=="«"){number = eq.substring(i,pos-1); firstIndex = i-1;}/*number is negative*/
			else if(eq.charAt(pos-1)=="»"){number = eq.substring(i+1,pos-1); firstIndex = i;}/*'«' found*/
			else if(i==0 && isNaN(Number(charValue))) {number = eq.substring(i+1,pos); firstIndex = i+1;}/*found at first index of equation*/
			else if(i==0){number = eq.substring(i,pos); firstIndex = i;}/*first index of equation is part of number*/
			else{number = eq.substring(i+1,pos); firstIndex = i+1;}
			i=-2;/*get out of for loop*/
		}
	}

	for(i=pos+2;i<eq.length;i++)/*look for last index of exponent (similar to solveLOG(eq,pos))*/
	{
		charValue=eq.charAt(i);
		
		if(i == eq.length-1 || charValue == "»"  || charValue == "+" || charValue == "-" || charValue == "*" || charValue == "/" || charValue == "a" || charValue == "s" || charValue == "c" || charValue == "t" || charValue == "l")
		{
			if(((charValue == "+" || charValue == "-") && eq.charAt(i-1) == "e") || (charValue == "-" && eq.charAt(i-1) == "*")){}
			else
			{
				if(i==eq.length-1 && charValue!="»") i=i+1;
				exponent = eq.substring(pos+2,i);
				lastIndex = i;
				i=1e100;
			}
		}
	}
	/*do the math:*/
	number = Math.pow(number,exponent);
	if(number=="Infinity"){number="InfiniNaN"}/*number is out of computer range but exists*/

	return eq.replace(eq.substring(firstIndex,lastIndex),number);
}
/*the function solveAllMult(eq,type) solve an equation 'eq' composed of multiplication, division, addition and substraction.  Type sets the king writing the clean equation*/
function solveAllMult(eq,type)
{
	var innerEq = changeAddSign(eq);/*change the + and - signs appropriately*/
	var addPos = findAdd(innerEq);/*find index positions of all the + signs*/
	var subEq = new Array();/*an array of sub-equations (between all + signs)*/
	
	if (addPos!=-1)/*determines all sub-equations if more than one*/
	{/*record sub-equations:*/
		subEq[0] = innerEq.substring(0,addPos[0]);
		
		for(i=1;i<addPos.length;i++)
		{
			subEq[i] = innerEq.substring(addPos[i-1]+1,addPos[i]);
		}
		
		subEq[addPos.length] = innerEq.substring(addPos[addPos.length-1]+1);
	}
	else{subEq[0] = innerEq;}/*there are no addition or substraction in the equation*/

	var newEq=solveMult(subEq[0]);/*solve first sub-equation*/
	/*solve all other sub-equations:*/
	for(j=1;j<subEq.length;j++)
	{
		newEq = newEq + "+" + solveMult(subEq[j]);
	}
/*WRITING THE CLEAN EQUATION*/
	if(type==FINAL){writeCleanEq(newEq,type);}
	/*solve the addition and substraction:*/
	return solveAdd(newEq);
}
/*the function solveMult(eq) solve an equation 'eq' composed of multiplication, division*/
function solveMult(eq)
{	
	var innerEq=eq;
	var multPos = findMult(innerEq);/*find index positions of all the * and / signs*/
	var answer=1;

	if (multPos==-1){answer=innerEq;return answer;}/*equation is a number*/
	else
	{/*return the answer if one number is equal to infinity or do the multiplication or division for all arguments:*/
		/*first argument:*/
		if(innerEq.substring(0,multPos[0]) == "InfiniNaN"){answer="InfiniNaN"; return answer;}
		else if(innerEq.substring(0,multPos[0]) == "-InfiniNaN"){answer="-InfiniNaN"; return answer;}
		else{answer = answer * Number(innerEq.substring(0,multPos[0]));}
		/*other arguments:*/
		for(i=1;i<multPos.length;i++)
		{	
			if(innerEq.charAt(multPos[i-1]) == "*")
			{
				if(innerEq.substring(multPos[i-1]+1,multPos[i]) == "InfiniNaN"){answer="InfiniNaN"; return answer;}
				else if(innerEq.substring(multPos[i-1]+1,multPos[i]) == "-InfiniNaN"){answer="-InfiniNaN"; return answer;}
				else{answer = answer * Number(innerEq.substring(multPos[i-1]+1,multPos[i]));}
			}
			else
			{
				if(innerEq.substring(multPos[i-1]+1,multPos[i]) == "InfiniNaN"){answer=0; return answer;}
				else if(innerEq.substring(multPos[i-1]+1,multPos[i]) == "-InfiniNaN"){answer=0; return answer;}
				else{answer = answer / Number(innerEq.substring(multPos[i-1]+1,multPos[i]));}
			}
		}
		/*last argument:*/
		if(innerEq.charAt(multPos[multPos.length-1]) == "*")
		{
			if(innerEq.substring(multPos[multPos.length-1]+1) == "InfiniNaN"){answer="InfiniNaN"; return answer;}
			else if(innerEq.substring(multPos[multPos.length-1]+1) == "-InfiniNaN"){answer="-InfiniNaN"; return answer;}
			else{answer = answer * Number(innerEq.substring(multPos[multPos.length-1]+1));}
		}
		else
		{
			if(innerEq.substring(multPos[multPos.length-1]+1) == "InfiniNaN"){answer=0; return answer;}
			else if(innerEq.substring(multPos[multPos.length-1]+1) == "-InfiniNaN"){answer=0; return answer;}
			else{answer = answer / Number(innerEq.substring(multPos[multPos.length-1]+1));}
		}
	}

	return answer;
}
/*the function findMult(eq) find all the index positions of * or / in the equation 'eq'*/
function findMult(eq)
{	
	var parPos = new Array();
	var j=0;
	var pos;
	var temp1;
	var temp2;

	parPos[0]=-1;

	temp1 = eq.indexOf("*",0); 
	temp2 = eq.indexOf("/",0); 

	if (temp1==-1 && temp2==-1){return parPos;} /*none found*/
	else
	{
		for(i=0;i<eq.length;i++)
		{
			if(eq.charAt(i) == "*"  || eq.charAt(i) == "/")
			{
				parPos[j]=i;
				j=j+1;
			}
		}
	}
	return parPos;
}
/*the functions changeAddSign(eq) changes all the + and - signs to the appropriate one (either +- or +) in the equation 'eq'*/
function changeAddSign(eq)
{
	var innerEq = eq.replace(/\+-/g,"-");/*change all +- to -*/
	innerEq = innerEq.replace(/--/g,"+");/*change all -- to +*/
	innerEq =innerEq.replace(/-/g,"+-");/*change all - to +-*/
	innerEq =innerEq.replace(/\++/g,"+");/*change all ++ to +*/
	innerEq =innerEq.replace(/\*\+/g,"*");/*change all *+ to */
	innerEq =innerEq.replace(/\/\+/g,"/");/*change all /+ to / */
	innerEq =innerEq.replace(/e\+/g,"e");/*change all e+ to e*/
	if(innerEq.charAt(0) == "+"){innerEq =innerEq.replace("+","");} /*if first character is a +, remove it*/
	
	return innerEq;	
}
/*the function solveAdd(eq) solves the addition and substraction in the equation 'eq'*/
function solveAdd(eq)
{
	var innerEq=eq;
	if (isNaN(Number(innerEq))){innerEq = changeAddSign(innerEq);}/*change the + and - sign to the appropriate one (all - are converted to +-)*/
	var addPos = findAdd(innerEq);/*find the index positions of all + signs*/
	var answer=0;

	if (addPos==-1){answer=innerEq; return answer;}/*if there is no + sign, equation is a number*/
	/*return the answer if one number is equal to infinity or do the addition for all arguments:*/
	/*first argument:*/
	if(innerEq.substring(0,addPos[0])=="InfiniNaN"){answer="InfiniNaN"; return answer;}
	else if(innerEq.substring(0,addPos[0])=="-InfiniNaN"){answer="-InfiniNaN"; return answer;}
	else{answer = answer + Number(innerEq.substring(0,addPos[0]));}
	/*other arguments:*/
	for(i=1;i<addPos.length;i++)
	{
		if(innerEq.substring(addPos[i-1]+1,addPos[i])=="InfiniNaN"){answer="InfiniNaN"; return answer;}
		else if(innerEq.substring(addPos[i-1]+1,addPos[i])=="-InfiniNaN"){answer="-InfiniNaN"; return answer;}
		else{answer = answer + Number(innerEq.substring(addPos[i-1]+1,addPos[i]));}
	}
	/*last arguments:*/
	if(innerEq.substring(addPos[addPos.length-1]+1)=="InfiniNaN"){answer="InfiniNaN"; return answer;}
	else if(innerEq.substring(addPos[addPos.length-1]+1)=="-InfiniNaN"){answer="-InfiniNaN"; return answer;}
	else{answer = answer + Number(innerEq.substring(addPos[addPos.length-1]+1));}

	return answer;
}
/*the function findAdd(eq) find all the index positions of + in the equation 'eq'*/
function findAdd(eq)
{
	var parPos = new Array();
	var j=0;
	var pos;
	
	parPos[0]=-1;

	for (pos=0;pos<eq.length;pos++)
	{
		pos = eq.indexOf("+",pos); 
		if (pos!=-1)
		{
			parPos[j]=pos;
			j=j+1;
		}
		else{return parPos;}
		
	}
	return parPos;
}
/*the function findOpenPar(eq) find all the index positions of « in the equation 'eq'*/
function findOpenPar(eq)
{
	var parPos = new Array();
	var j=0;
	var pos;
	
	parPos[0]=-1;

	for (pos=0;pos<eq.length;pos++)
	{
		pos = eq.indexOf(String.fromCharCode(171),pos); 
		if (pos!=-1)
		{			
			parPos[j]=pos;
			j=j+1;
		}
		else{return parPos;}
	}
	return parPos;
}
/*the function findClosePar(eq) find all the index positions of » in the equation 'eq'*/
function findClosePar(eq)
{
	var parPos = new Array();
	var j=0;
	var pos;
	
	parPos[0]=-1;

	for (pos=0;pos<eq.length;pos++)
	{
		pos = eq.indexOf(String.fromCharCode(187),pos); 
		if (pos!=-1)
		{			
			parPos[j]=pos;
			j=j+1;
		}
		else{return parPos;}
	}
	return parPos;
}
/*the function fillEq(innerEq) find and add all missing parenthesis and implied multiplication in the equation 'innerEq'*/
function fillEq(innerEq)
{
	var eq = innerEq;

	for(i=0;i<eq.length;i++)/*check each character in equation*/
	{
		value = eq.charAt(i);
		/*if a function is followed by another function, insert an opening parenthesis:*/
		if ((value=="s" || value=="c" || value=="t" || value=="g" || value=="b" || (value=="n" && eq.charAt(i-1)=="l")) && i!=eq.length-1)
		{
			var nextValue = eq.charAt(i+1);
			if (nextValue=="s" || nextValue=="c" || nextValue=="t" || nextValue=="l" || nextValue=="a")
			{eq = eq.substring(0,i+1) + "«" + eq.substring(i+1);}
		}
		/*if a function or opening parenthesis is preceded by a number or a closing parenthesis, insert a *: */
		if (i!=0 && ((value=="s" && eq.charAt(i-1)!="a") || (value=="c" && eq.charAt(i-1)!="a") || (value=="t" && eq.charAt(i-1)!="a") || value=="l" || value=="a" || value=="«" || value=="p" || (value=="n" && eq.charAt(i-1) != "l")))
		{
			var previousValue = eq.charAt(i-1);
			if (previousValue != "*"  && previousValue != "+"  && previousValue != "-"  && previousValue != "/"  && previousValue != "s"  && previousValue != "c"  && previousValue != "t"  && previousValue != "g"  && previousValue != "b"  && (previousValue != "n" && eq.charAt(i-2) != "l")  && previousValue != "«")
			{eq = eq.substring(0,i) + "*" + eq.substring(i); i=i+1;}
		}
		/*if pi, Euler's number or closing parenthesis is followed by somehing else than /*-+», insert a *: */
		if ((value=="p" || (value=="n" && eq.charAt(i-1) != "l") || value=="»") && i!=eq.length-1)
		{
			var nextValue = eq.charAt(i+1);
			if (nextValue!="*" && nextValue!="+" && nextValue!="-" && nextValue!="/" && nextValue!="»")
			{eq = eq.substring(0,i+1) + "*" + eq.substring(i+1);}
		}
	}
	/*find missing parenthesis:*/
	var open;
	var close;
	var diff;
	for(j=1;j<=2;j++)/*do it twice*/
	{
		open = findOpenPar(eq);/*find all index positions of opening parenthesis*/
		close = findClosePar(eq);/*find all index positions of closing parenthesis*/
		diff=0;/* = number of open - number of close */
		
		if(open[0]==-1 && close[0]==-1){}/*no parenthesis --> do nothing*/
		else if(open[0]==-1){diff = -close.length;}/*only closing parenthesis present*/
		else if(close[0]==-1){diff = open.length;}/*only opening parenthesis present*/
		else{diff = open.length-close.length;}/*find diff*/
		
		for(i=1;i<=diff;i++){eq=eq+"»";}/*add closing parenthesis as needed*/
		for(i=1;i<=-diff;i++){eq="«"+eq;}/*add opening parenthesis as needed*/
		if(diff==0 && (open[0]>close[0] || open[open.length-1]>close[close.length-1]))/*all closing are before all opening parenthesis*/
		{/*add opening and closing parenthesis as needed:*/
			for(i=1;i<=open.length;i++){eq=eq+"»";}
			for(i=1;i<=close.length;i++){eq="«"+eq;}
		}
	}
	return eq;
}
