function showdiv(w){
	// alert(w);
	// var d=window.navigator.appName.toLowerCase().indexOf("netscape")!= -1 ? document[w] : eval(w).style;
	document.getElementById(w).style.visibility='visible';
	}
var  BASE=10,MAXINT=2*(Math.pow(2,30)-1)+1 , pstart="[",pend="]";

var maxDIGlen=MAXINT.toString().length;

var clearansTXT='The recurring part of a decimal is shown between '+pstart+' and '+pend
     +' brackets: eg\r3/44 = 0.06'+pstart+'81'+pend
     +' means 3/44 = 0.06818181...\r';

function MSG(xx){   var s;
      if(arguments.length==1 && typeof arguments[0]=="object")s=arguments[0]
 else if( arguments.length>0)s=arguments;
 alert(s.join(''))
}; 
function IgnoreError(){self.onerror=ProcessErrors; return true};
function ProcessErrors(){return false};
function STOP(){  self.onerror=IgnoreError;  xxhaltxx() };
function ERR(xx){ MSG(arguments);  STOP()};
function ERRoverflow(m){ERR('Sorry, I cannot compute the answer because\r'
  +'the calculations involve numbers that have become too large!')};
function isOK(msg){ 
  if(arguments.length>1)msg=arguments.join('');
  if(!confirm(msg))STOP() 
};

function gcd(a,b){  return gcd1(Math.abs(a),Math.abs(b))  };function gcd1(a,b){  
        if(a==0) return b
   else if(b==0) return a
   else return gcd1(b%a,a)
};

function lcm(a,b){ return a/gcd(a,b)*b };
function powmod(Base,Pow,Mod){ 
  var pm;  
       if(Pow==0)pm= 1
  else if(Pow==1)pm= Base%Mod
  else if(Pow>1)
       {var s=powmod(Base,Math.round((Pow-Pow%2)/2),Mod);
        var ss=mul(s,s)%Mod;
        pm= (Pow%2==0 ? ss : (Base*ss)%Mod )  } ;
  return pm     
};
function isprime(N){ 
  if(N%2==0)return (N==2);
  var i=3,L=Math.sqrt(N),ct=0;
  var stime=(new Date()).getTime();
  while(i<=L && N%i!=0){i=i+2; ct++};  var inctime=(new Date()).getTime()-stime;  
  return(N>1 && i>L)
};

function primefactors(N){   
    if(N==1)return [1];
    var f=new Array(), II=N,L=Math.sqrt(N);
    while(II%2==0){f=f.concat(2);II=II/2;L=Math.sqrt(II)};
    for(var i=3;i<=L;i=i+2)
       while(i<=L && II%i==0){f=f.concat(i);II=II/i;L=Math.sqrt(II)};
    if(II>1)f=f.concat(II);
    return f
};
function factors(N){  
  if(N==1)return [1];
  return cpfrom([],0,ordlistToZbag(primefactors(N)),function(L){return eval(L.join('*'))})
   .sort(function(a,b){return a-b});
};

function cpfrom(PrevAnss,Li,L,F){ 
   if(L.length==Li)return F(PrevAnss);
   var ans=[];
   for(var i=0;i<=L[Li][1];i++)
      ans=ans.concat(cpfrom(PrevAnss.concat(Math.pow(L[Li][0],i)), Li+1, L, F));
   return ans
};
function ordlistToZbag(L){    
   var s=L[0],ct=1,i,z=[];
   for(var i=1;i<L.length;i++)
     if(L[i]==s)ct++
     else {z=z.concat([[s,ct]]);s=L[i];ct=1};
   z=z.concat([[s,ct]]);
    return z
};
function EulerPhi(N){  
  var pfs=ordlistToZbag(primefactors(N));
  var phi=1,i=0;
  while(i<pfs.length)  {var pr=pfs[i][0],po=pfs[i][1]; i++; phi=phi*Math.pow(pr,po-1)*(pr-1)}; 
 return phi
};

function maxdps(w){return getn("ndps",w)[0]};

function setmaxdps(w){var fld=document["frac"+w].ndps;
  var MAXNDP=getn("ndps",w)[0];
  if(isNaN(MAXNDP) || MAXNDP<1){fld.value=10;ERR("Your 'Number of dps' value is not a valid number so I've reset it to "+MAXNDP) }
  else if(MAXNDP>1000)
         if( ! confirm("Do you really want more than 1,000 decimal places computed?"))
            fld.value=1000;
};

function put(w,X){  var s=""; 
  for(var i=1;i<arguments.length;i++)  s=s+arguments[i];
  s=s+"\r";  
  document["frac"+w].ans.value=document["frac"+w].ans.value+s;
};

function mul(a,b){if(a==0)return 0
  else if((a*b)/a!=b){ERRoverflow(a+" MUL "+b)}else{return a*b}
};
function add(a,b){if((a+b)-a!=b){ERRoverflow(a+" ADD "+b)}else{return a+b}
};
function isINT(N,nm){if(typeof N != "string")N=N.toString();
  if(N.length>maxDIGlen )
        ERR("Your "+nm+" number "+N+" is too large.\rIt may have no more than ",maxDIGlen," digits.");
  if(N>MAXINT)ERR("Sorry - your "+nm+" number "+N+" is too big.\rThe maximum number I can use is "+MAXINT+".");
};

function getn(fld,w){  
  var boxname=(fld=="numer"?"top (numerator)"
              :fld=="denom"?"bottom (denominator)"
              :fld=="ndps"?"number of decimal places"
              :"");
  var str=stripspace(eval("document.frac"+w+"."+fld+".value"));
  if(str.match(/[^0-9,]/)!=null)
    ERR("The "+boxname+" box must only contain digits:\n"+str);
  var nbsRAW=str.replace(/\s|,/g,"").match(/\d+/g); 
  var nbs=nbsRAW;  
  if(!nbs || typeof nbs!="object" || nbs.length==0)ERR("I didn't find a number in the "+boxname+" input box.\n \nPlease enter a number and try again.");
  isINT(nbs[0],boxname); if(nbs[1]){isINT(nbs[1],"")}else{nbs[1]=nbs[0]};
  for(var i=0;i<nbs.length;i++)nbs[i]=parseInt(nbs[i],10);
  if(nbs.length==2)
      {if(nbs[1]<nbs[0])
         ERR("The end of the range ("+nbs[1]+") is less that its start ("+nbs[0]+")")}
  else if(nbs.length==1)nbs[1]=nbs[0]
  else ERR('You have given me ',nbs.length,' numbers in the "+boxname+" box. Please give just 1.');
  if(fld=="denom" && nbs[0]<2)ERR("The denominator must be 2 or more");  
  return nbs  
};

function getF(w){  return ratsimp(getn("numer",w)[0] ,getn("denom",w)[0] ) } ;
function ratsimp(n,d){ 
  if(typeof n=="string")n=parseInt(n,10);    if(typeof d=="string")d=parseInt(d,10);
   var g=gcd(n,d); 
   if(g>1){var ans= {num:Math.round(n/g), den:Math.round(d/g)}}
   else var ans= {num:n, den:d} ;
   return ans
};
function top(){return getF().num};
function bot(){return getF().den};

function newPFs(w){
  document["frac"+w].denomPFs.value=ordlistToZbag(primefactors(getF(w).den)); 
};
function nonrecPer(w,N,D){ 
  if(N/D>=1){ERR(N+"/"+D+" is not a proper fraction (it must be < 1)")}
  else {var F=ratsimp(N,D);N=F.num;D=F.den;    
        var p2=0;  while(D%2==0){p2++;D=Math.round(D/2)};
        var p5=0;  while(D%5==0){p5++;D=Math.round(D/5)};        var nonrecLen=Math.max(p2,p5);    
        return [nonrecLen,(D==1 ? 0 : order10(D)) ]
       }
};
function firstdp(N,D){ 
  var p1=Math.floor(10*N/D);
  return [p1,10*N-p1*D]
};
function putdecs(w,N,D,maxnb){  
  if(arguments.length<4)maxnb=maxdps(w);
  var np=nonrecPer(w,N,D);
  var nonreclen=np[0], per=np[1],i=0;
  if(np.length==0){putrawdecs(w,N,D,maxnb);return};
  var dps="0.",R=N,dr;
  for(var i=1;i<=Math.min(nonreclen,maxnb);i++)
      {dr=firstdp(R,D); dps=dps+dr[0].toString(); R=dr[1] };
  if(i>maxnb){dps=dps+"...";return dps};
  if(per>0)dps=dps+pstart;
  for(var i=nonreclen+1;i<=Math.min(nonreclen+per,maxnb);i++)
      {dr=firstdp(R,D);dps=dps+dr[0].toString();R=dr[1] };
  if(i<=nonreclen+per)dps=dps+"...";
  if(per>0)dps=dps+pend;
  return dps
};
function putrawdecs(w,N,D,maxnb){
  if(arguments.length<4)maxnb=maxdps(w);
  var dps="0.",R=N,dr;
  for(var i=1;R>0 && i<=maxnb;i++)
      {dr=firstdp(R,D); dps=dps+dr[0].toString(); R=dr[1] };
  if(R>0)dps+="...";
  return dps
};

function doPowMod(w){
  var b=getn("numer")[0],pp=getn("denom");
  for(p=pp[0];p<=pp[1];p++)put(w,b,"^",p," mod 10 = ",powmod(b,p,10))
};
function order10(N){ 
  if(N==1)return 1;    
  var fs=factors(EulerPhi(N)),i=0;  
  while(powmod(10,fs[i],N)!=1)
    {  i++;if(i>fs.length)ERR("ERROR found [overrun in order10].\rPlease email your input numbers to R.Knott@altavista.net. Thank you.")};
  return fs[i]
};

function doTerminates(w){ 
 var ds=getn("denom",w);
 var nn=getn("numer",w)[0]; 
  
 for(var d=ds[0];d<=ds[1];d++)
    {var F=ratsimp(nn,d); 
     
     var np=nonrecPer(w,F.num,F.den);
     put(w,nn,'/',d,(nn==F.num?"":"="+F.num+'/'+F.den),
           (np[0]>0
           ?(np[1]==0
             ?" terminates after "+np[0]+" digit"+(np[0]>1?"s":"") 
             : " has "+np[0]+" initial digit" +(np[0]>1?"s":"") 
              +" followed by a period of "+np[1]+" digit"+(np[1]>1?"s":"")
             )
           :" is purely recurring with a period of "+np[1] +" digit"+(np[1]>1?"s":"")
           ),".")
     };
};

function doDecs(w,raw){
  var ds=getn("denom",w),nn=getn("numer",w)[0];
  for(var d=ds[0];d<=ds[1];d++)
     {var F=ratsimp(nn,d);       
      put(w,F.num,'/',F.den," = ",(raw?putrawdecs:putdecs)(w,F.num,F.den)) }
};
function stripspace(s){ 
  if(typeof s != "string")s=s.toString();
  return s.replace(/\s/g,"")
};
function nbdigs(n){ 
    if(typeof n!="string")ERR("nbdigs applied to non-string: "+n);
    return (n+" ").indexOf(" ")
};

function decToFrac(w){  
  var fxd=document["frac"+w].decf.value,  rpt=document["frac"+w].decrpt.value,F;
  fxd = stripspace(fxd);  rpt = stripspace(rpt);
  if(fxd.match(/[^0-9]/)!=null)
      {if(document["frac"+w].decf.value.indexOf(".")!=-1)
          ERR("Only give the part of the number AFTER the decimal point (the fractional part).");
        else ERR("The fixed part does not contain just digits")
      };
  if(rpt.match(/[^0-9]/)!=null)ERR("The repeating part does not contain just digits");
  if(fxd=="" && rpt=="") ERR("To use this button, first type in a decimal number to be converted to a fraction .");
  isINT(fxd,"FIXED"); isINT(rpt,"RECURRING");
  if(rpt=="") {F=ratsimp(fxd,Math.pow(10, nbdigs(fxd)))}
  else { var rexp=nbdigs(rpt),             fexp=nbdigs(fxd);  
         if(fxd=="")fxd='0';         
         F=ratsimp(add(mul(fxd,(Math.pow(10,rexp)-1)),parseInt(rpt,10)),
                   mul(Math.pow(10,fexp),(Math.pow(10,rexp)-1)))
     };  
  document["frac"+w].Dnumer.value=F.num;  document["frac"+w].Ddenom.value=F.den;
  put(w,"0."+document["frac"+w].decf.value+(document["frac"+w].decrpt.value==""?"":pstart+document["frac"+w].decrpt.value+pend)+"="
      +F.num+"/"+F.den);
};

function clearDecToFrac(w,x){ 
  document["frac"+w].Dnumer.value="";document["frac"+w].Ddenom.value="";
  if(arguments.length>1){document["frac"+w].decf.value=""; document["frac"+w].decrpt.value=""}
};

function selectfrac(w){
  if(document["frac"+w].egs.selectedIndex>0)
    {var nd=document["frac"+w].egs[document["frac"+w].egs.selectedIndex].value; 
     var nd="document.frac"+w+".numer.value="+nd.replace(",",";document.frac"+w+".denom.value="); 
     eval(nd)
    }
};