 var Phi=(Math.sqrt(5)+1)/2, phi=Phi-1;function DoERROR(){return false};function resetERROR(){self.onerror=DoERROR;return true};function HALT(msg){alert("**Problem**\r"+msg);self.onerror=resetERROR;ERROR();alert("aagh - after HALT")};var ErrorAt="",ErrorIn="";function ERRORHandler(msg,error,line){alert("There is a problem with "+ErrorAt+":\r"+ErrorIn+" is not a number.");return true};//  Make a window Pop Upvar debug=false,record=false;var _auxwin;if(debug){_auxwin=window.open("","tip","width=500,height=400,scrollbars=yes,resizable=yes,status=yes");          _auxwin.document.open("text/plain")         };function _AuxWinOpen(typ){  //default typ=="html"  //alert(typ);  _auxwin=window.open("","tip","width=500,height=400,scrollbars=yes,resizable=yes,status=yes");    //if already open, does nothing  //if(typ && typ=="plain"){_auxwin.document.open("text/plain")}else{_auxwin.document.open()};  _auxwin.focus()  };function DBG(args){  //no args means clear _auxwin window  if(!debug)return;  if(arguments.length==0){_auxwin.document.close();_auxwin.document.open("text/plain");}  else {for(var i=0;i<arguments.length;i++)          _auxwin.document.write(arguments[i]);        _auxwin.document.writeln();       };};var CFtrunc=Math.floor;  //or Math.ceil or Math.round function getRNS(){  var r=isINT(document.f.R.value,"the first number in the numerator of the Fraction",0),      n=isINT(document.f.N.value,"the value square-rooted in the numerator of the Fraction",0),      s=isINT(document.f.S.value,"the denominator of the Fraction",1);  if(n<0)HALT("The square-root of a negative number is not allowed.");  if(document.f.SGN[document.f.SGN.selectedIndex].value=="-"||s<0&&r<0&&n==0)     {r=-r;s=-s};  return {R:r,N:n,S:s}};function setRNS(r,n,s){   if(r=="")r=0; if(n=="")n=0; if(s=="")s=1;  if(s<0){r=-r;s=-s;document.f.SGN.selectedIndex=1}else{document.f.SGN.selectedIndex=0};  document.f.R.value=(r==0?"":r);document.f.N.value=(n==0?"":n);document.f.S.value=(s==1?"":s)};  function showrns(r,k,n,s){ // ( r+ksqrt(n) )/s  if(debug)DBG("show("+r+","+k+","+n+","+s+")");  if(s<0){r=-r;k=-k;s=-s};  var top=(r!=0?r:"")        +(n!=0?(r!=0&&k>0?"+":k<0?"-":"")               +(Math.abs(k)!=1?Math.abs(k):"")               +"sqrt("+n+")"         :"");  return (s!=1 ? (n==0||r==0?"":"(") : "")         + top +         (s!=1 ? (n==0||r==0?"":")") : "")         +(s==1?"":"/"+s)};function showrnsdc(r,n,s,d,c){    if(debug)DBG("showrnsdc("+r+","+n+","+s+","+d+","+c+")");   var k=(n!=0?Math.sqrt(sqrfactor(n)):1); var nk=(k!=1?Math.round(n/k/k):n);  // ASSERT sqrt(n) = k sqrt(nn)  if(s<0){s= -s;r=-r;k=-k}  return (r!=0||n!=0||s!=1?showrns(r,(k<0?-1:1),n,s)     +(k!=1&&k!=-1&&nk!=1?" = "+showrns(r,k,nk,s):"")+" = ":"")    +d+(c!=d?" = "+c:"")}; function recrd(){ // if(!document.ans.Record.checked)return; var rns=getRNS(); var r=rns.R,n=rns.N,s=rns.S,     d=document.f.dec.value,     c=Cf.cftoString();  document.ans.Recordtxt.value = document.ans.Recordtxt.value     +showrnsdc(r,n,s,d,c) +"\r";};function _AuxWinHTML(lines){  var TITLE="",i=0;  _AuxWinOpen("html");  if(beginswith(arguments[0],"OPT")){i=1;eval(arguments[0].substring(3))};  with(_auxwin.document)    {writeln("<html><head><title>",TITLE,"</title></head><body>");    for(i;i<arguments.length;i++)          writeln(arguments[i]);    writeln("<hr><div align=center>",    "<form><input type='button' value='Close' onClick='window.close()'>",    "<input type=reset value='Clear'></form>",    "</div></body></html>")    };  _auxwin.document.close()}function _AuxWinPlain(msg){  _AuxWinOpen("plain");  with(_auxwin.document)    for(var i=0;i<arguments.length;i++)          writeln(arguments[i]);  _auxwin.document.close()}// -------------function endswith(a,b){  //alert("endswith "+a+"  "+b);    if(typeof(a)!="string")a=a.toString();    if(typeof(b)!="string")b=b.toString();    var la=a.length; var lb=b.length;    if(la<lb)return false    else return(a.substring(la-lb)==b)};function isempty(fld,alt){return (fld.replace(/\s/g,"")=="" || (arguments.length==2 ? fld==alt : false) ) };function gcd(a,b){  return gcd1(Math.abs(a),Math.abs(b))  };function gcd1(a,b){  //ASSERT a>=0, b>=0        if(a==0) return b   else if(b==0) return a   else return gcd1(b%a,a)};function isINT(v,txt,e){var i;   v=v.replace(/,/g,"").replace(/\s/g,"");  if(v.indexOf(".")!=-1)HALT(txt+" must be a whole number.\rUse the 'Decimal:' box for decimal number values.");  if(v==""){if(arguments.length>=3){return e}else{return Number.NaN}};  ErrorAt=txt;ErrorIn=v;self.onerror=ERRORHandler;i=eval(v);self.onerror=DoERROR;  if(isNaN(i))HALT(txt+" is not a number.");  if(i.toString()!=v && v.replace(/\d/g,"")=="")HALT("The number "+txt+" is too long:\r"+v);  return i};function isREAL(v,txt,e){   v=v.replace(/,/g,"").replace(/\s/g,"");  if(v==""){if(arguments.length>=3){return e}else{return Number.NaN}};  var r=parseFloat(v);  if(isNaN(r))HALT(txt+" is not a number.");  return r};function justify(s,fw,opt){var i;  if(typeof s != "string")s=s.toString();  if(arguments.length<3)opt="L";       if(opt=="L")for(i=s.length;i<fw;i++)s=s+" "  else if(opt=="R")for(i=s.length;i<fw;i++)s=" "+s;  else if(opt=="C")for(i=s.length;i<fw;i++)s=(i%2==0?" "+s:s+" ");  return s}; function SIGN(x){return (x==0?0:x<0?-1:1)};var Cf=new CF();     function cfSHOW(){  //alert("cfSHOW "+Cf);  var s="";  if(Cf.cf.length==0){document.f.cf.value=""}  else  {  var i;     document.f.cf.value=Cf.cftoString();       s=Cf.cvgtstoString()  };  document.ans.morecf.value=(s==""?" ":s);};function ratSHOW(Rat){  //alert("ratSHOW "+Rat);   setRNS(Rat.top,"",Rat.bot);     Sqrt2Dec(Rat.top,0,Rat.bot);};   function sqrfactorXX(n){var N=n;if(n==0)return 1;  if(n<0)n=-n;  var sqrtn=Math.sqrt(n),floorsqrtn=Math.floor(sqrtn);  var nonsqr=Math.round((sqrtn-floorsqrtn)*(sqrtn-floorsqrtn)-floorsqrtn*floorsqrtn+2*floorsqrtn*sqrtn);  alert("sqrfactor of "+n+"="+nonsqr+"*"+(n/nonsqr));  return Math.round(n/nonsqr)};function sqrfactor(n){var N=n;if(n==0)return 1;  if(n<0)n=-n;  var f=1,lim=Math.sqrt(n);  if(debug)DBG("\rsqrfactor of "+n+ " lim="+lim);  if(lim>100000)     if(!confirm("To simplify the fraction may take a while - do you still want simplification?"))         {return 1};   while(n%4==0){f=f*4;n=Math.round(n/4)};  //if(n<9)return f;  for(var i=3,ii=9;n>=ii && i<=lim;i=i+2,ii=i*i)     {//if(debug)DBG("sqrf i="+i+" ii="+ii+" n="+n);      while(n>=ii && n%ii==0){f=f*ii;n=Math.round(n/ii)      //if(debug)DBG(" ..f="+f+" n="+n)     }};  if(debug)DBG("sqrfactor of "+N+" = "+f+" *"+n);  return f};function simplifyrns(r,n,s){  //check for common factors...  // var FF=sqrfactor(n);var F=Math.round(Math.sqrt(FF));  //n=F*F*(n/FF)  var g=gcd(r,Math.round(Math.sqrt(sqrfactor(gcd(n,s*s)))));  if(debug)DBG("r="+r+" n="+n+" s="+s+"  g="+g);  r=Math.round(r/g);s=Math.round(s/g);n=Math.round(n/(g*g));  return [r,n,s]}function sqrtSHOW(r,n,s){  var rns=simplifyrns(r,n,s);  r=rns[0];n=rns[1];s=rns[2];  setRNS(r,n,s);  Sqrt2Dec();};  function evalDec(){var v; try { with(Math){ v=eval(document.f.dec.value.replace(/Pi/ig,"PI") )};   }catch(e){HALT(" The decimal expression cannot be evaluated - please correct it")}; if(typeof v == "undefined")HALT(" Please type a number into the Decimal box"); if(v<0)HALT("Decimal Value is negative"); if(!isFinite(v))HALT("The decimal is too large - sorry"); if(v==0)HALT("The decimal value is too small - sorry"); if(v!=document.f.dec.value)      document.ans.Recordtxt.value = document.ans.Recordtxt.value+document.f.dec.value+" = "; document.f.dec.value=v};    function rat2cf(r,s){ // r/s  var t=r,b=s,i=-1,q;   Cf.reset();   do{ q=CFtrunc(t/b);       r=t-q*b;       Cf.append(q);       t=b;b=r;   } while (r/=0 && !Cf.stopped);};function Rat2CF(r,s){ //ASSERT n = 0  if(debug)DBG("Rat2CF("+r+","+s+")");  if(arguments.length==0)  {var rnsin=getRNS();r=rnsin.R;s=rnsin.S}  var g=gcd(r,s);  if(g>1){document.ans.Recordtxt.value=document.ans.Recordtxt.value+r+"/"+s+" = ";            r=Math.round(r/g);s=Math.round(s/g);            setRNS(r,0,s)};  rat2cf(r,s);  cfSHOW();};function Real2CF(){   var i=-1;   Cf.reset();  clearxcpt('dec');   var r=isREAL(document.f.dec.value,"Your Decimal entry"),q;   if(isNaN(r))return;    if(r<0)HALT("Decimal value is negative");   do   {  q=CFtrunc(r);     if(isFinite(q)){Cf.append(q); r=1/(r-q)};   } while(!Cf.stopped && isFinite(r));   cfSHOW();      recrd();};function Sqrt2Dec(r,n,s){ //alert("Sqrt2Dec");  if(arguments.length==0)  {var rnsin=getRNS(); r=rnsin.R;n=rnsin.N;s=rnsin.S  };  var v=(r+Math.sqrt(n))/s;  if(v<0)HALT("The fraction is negative:"+v);  document.f.dec.value=v;  if(debug)DBG("_____Sqrt to Dec ____   ("+r+" +sqrt "+n+")/"+s+" = "+document.f.dec.value)};function Sqrt2CF(){  var rnsin=getRNS();var r=rnsin.R,n=rnsin.N,s=rnsin.S;  Sqrt2Dec(r,n,s);        if(n==0){Rat2CF(r,s)}  else{SqrtPeriodicCF(r,n,s)};  recrd();};  function SqrtPeriodicCF(r,n,s){  if(arguments.length==0)  {var rnsin=getRNS();r=rnsin.R;n=rnsin.N;s=rnsin.S};  Cf.reset();  var R=new Array();R[0]=r;  var S=new Array();S[0]=s;  var sqt=Math.floor(Math.sqrt(n));  if(sqt*sqt==n)  {Rat2CF(r+sqt,s)}  else  { if(n-R[0]*R[0] % S[0] !=0){R[0]=R[0]*Math.abs(S[0]);n=n*S[0]*S[0];S[0]=S[0]*Math.abs(S[0])};    var j=0;    for(i=1;j==0 && !Cf.cfOFLO;i++)      {Cf.append(Math.floor((R[i-1]+Math.sqrt(n))/S[i-1]));       R[i]=Cf.lastcf()*S[i-1]-R[i-1];       S[i]=(n-R[i]*R[i])/S[i-1];       for(j=i-1;j>0 && (R[j]!=R[i] || S[j]!=S[i]);j--){};      };     if(!Cf.cfOFLO){Cf.cfperiodLWB=j;Cf.cfperiodUPB=i-2}     while(!Cf.stopped)Cf.append(Cf.cf[j++]);   };   cfSHOW();    if(debug)DBG("______Sqrt to CF_____\r"+Cf.toString()+"\r"+document.f.dec.value+" ("+eval((-r+Math.sqrt(n))/-s)+")");};  function updateCF(){  var cf=document.f.cf.value.replace(/\.\.\./,"").replace(/\s/g,"").replace(/;/,',');    var e=cf.replace(/\[/,"").replace(/\]/,"").replace(/,/g,"").replace(/\d/g,"");  if(e.replace(/[-\.]/g,"")!="")     HALT("Your CF must contain ONLY numbers separated by , with '[' and ']' to show any period.\r I found "+e);  cf=eval("["+cf+"]");  Cf.reset();  for(var i=0;i<cf.length-1;i++)          if(typeof cf[i]=="object")  HALT("The periodic part of your CF can only be the LAST part.")     else if(typeof cf[i]!="number")  HALT("This item in your CF is not a number:\r"+cf[i])     else if(Math.floor(cf[i])!=cf[i])HALT("Your CF must contain only WHOLE numbers.\rI found "+cf[i])     else if(cf[i]==0 && i>0)         HALT("Only the first number in your CF can be 0.")     else if(cf[i]<0)                 HALT("You cannot have negative numbers in your CF.\rI found "+cf[i])     else                             Cf.append(cf[i]);  i=cf.length-1;      if(typeof cf[i] != "object"){Cf.append(cf[i])}  else {Cf.cfperiodLWB=i;        for(j=0;j<cf[i].length;j++){Cf.append(cf[i][j]); //alert("per elt "+cf[i][j])          };        Cf.cfperiodUPB=Cf.cf.length-1;        //alert("CF period from "+Cf.cfperiodLWB+" to "+Cf.cfperiodUPB);       i=Cf.cfperiodLWB;       while(!Cf.stopped)Cf.append(Cf.cf[i++]);       };  clearxcpt('cf');  cfSHOW();//confirm("updated!");  if(debug)DBG("_______new CF________\r"+Cf.toString())};function CF2Fract(){  updateCF();   if(!Cf.isPeriodic())ratSHOW(Cf.toRAT())  else CF2Sqrt();  recrd();};function CF2Sqrt(){var i; var CFp=new CF(),CFnp=new CF(); if(debug)DBG("_______CF to sqrt__________\r");  // CFp.append(0); for(i=Cf.cfperiodLWB;i<=Cf.cfperiodUPB;i++)  CFp.append(Cf.cf[i]); if(CFp.stopped)HALT("The period of your CF is too long"); if(debug)DBG("\rCFp: "+CFp.toString());  //-----PERIODIC PART --------- var penultR=CFp.cvgt[CFp.cf.length-2],lastR=CFp.cvgt[CFp.cf.length-1],R,N,S; //alert("Period expr from "+penultR+" "+lastR); var p2=penultR.top,q2=penultR.bot,p1=lastR.top,q1=lastR.bot; var r=p1-q2,n=(p1-q2)*(p1-q2)+4*p2*q1,s=2*q1; var rns=simplifyrns(r,n,s);r=rns[0];n=rns[1];s=rns[2]; var d1=(r+Math.sqrt(n))/s,d2=(-r+Math.sqrt(n))/(-s),dd=CFp.toDec(),pdec=d1; if(debug)DBG("final  p cvgts:"+penultR+","+lastR+"\r r=",r," n=",n," s=",s,       " x=",d1,"  or  ",d2,       "\r-------CHECK d1: RHS=",(p1*d1+p2)/(q1*d1+q2),"  d2:",(p1*d2+p2)/(q1*d2+q2),"\r--------"); if(Math.abs(d1-dd)>Math.abs(d2-dd)){r=-r;s=-s;pdec=d2} if(debug)DBG(" and nearest to ",dd," is r=",r," s=",s);  //----INITIAL NON-PERIODIC PART--------- if(Cf.cfperiodLWB>0)   {for(i=0;i<Cf.cfperiodLWB;i++)CFnp.append(Cf.cf[i]);    if(CFnp.stopped)HALT("The initial (non-period) part of your CF is too long.");    if(debug)DBG("CFnp: "+CFnp.toString());    var nppenult=CFnp.cvgt[CFnp.cf.length-2],nplast=CFnp.cvgt[CFnp.cf.length-1];    var P1=nplast.top,Q1=nplast.bot,P2=nppenult.top,Q2=nppenult.bot;    var truedec=Cf.toDec();    if(debug)DBG("final np cvgts:"+nppenult+","+nplast,       "\r---------CHECK: x=",truedec,"  RHS=",(P1*pdec+P2)/(Q1*pdec+Q2),"\r--------");    //var R=(B*r+D*s)*(A*r+C*s)-A*n*B,N=(A*D-B*C)*(A*D-B*C)*s*s*n,S=(B*r+D*s)*(B*r+D*s)-B*B*n;    var alpha=P1*r+P2*s,beta=Q1*r+Q2*s,gamma=beta*P1-alpha*Q1;    R=alpha*beta-P1*Q1*n,S=beta*beta-Q1*Q1*n,N=n*gamma*gamma;    if(  R+P1*Q1*n!=alpha*beta      || S+Q1*Q1*n!=beta*beta      || Math.round(N/gamma)!=n*gamma      )HALT("A number has become too large (some digits have been lost).\rSorry - cannot convert this to a fraction");    if(debug)DBG("\rto simplify: R=",R," N=",N," S=",S)   var RNS=simplifyrns(R,N,S);R=RNS[0];N=RNS[1];S=RNS[2];   //var G=gcd(R,gcd(S,gamma));    //if(debug)DBG("\r---GCD?------ R=",R," S=",S," gamma=",gamma," GCD=",G);    //R=Math.round(R/G);S=Math.round(S/G);gamma=Math.round(gamma/G);N=n*gamma*gamma;    //if(debug && G!=1)DBG("\rGCDed elim: R",R," S=",S," N=",N);    var Dec1=(R+Math.sqrt(N))/S,Dec2=(-R+Math.sqrt(N))/(-S);    if(debug)DBG("\r("+R+" +sqrt "+N+")/ "+S+ "   Dec="+Dec1+" or "+Dec2);    if(Math.abs(Dec1-truedec)>Math.abs(Dec2-truedec))  {R=-R;S=-S};   } else{R=r;N=n;S=s}; sqrtSHOW(R,N,S); if(debug)DBG("___dec showing___ "+document.f.dec.value);};function CFalt(){ //alert("CFalt "+cf.length+" elts;last is ="+cf[cf.length-1]+(cf[cf.length-1]==1));  //document.ans.Recordtxt.value = document.ans.Recordtxt.value+Cf.dump();  if(Cf.isPeriodic()){alert("Periodic (infinite) CFs do not have an alternative ending");return};  Cf.altcf();  cfSHOW();};function egSHOW(){  var which=document.f.eg[document.f.eg.selectedIndex].value;       if(which==""){alert("Use the '"+document.f.eg[0].value+"' selector to choose which kind of example.")}  else if(which=="egfr"){setRNS(3,0,50); clearxcpt('fract');             pushme(document.ratRbtn)}  else if(which=="egdec"){document.f.dec.value="0.123456790123";clearxcpt('dec');pushme(document.decRbtn);}  else if(which=="egpi"){document.f.dec.value="pi";clearxcpt('dec');pushme(document.decRbtn);}  else if(which=="egsqrt"){setRNS(0,6,1);clearxcpt('fract');pushme(document.ratRbtn);}  else if(which=="egcfrat1"){document.f.cf.value="0,1,2,3";clearxcpt('cf'); pushme(document.cfLbtn);document.ans.morecf.value=" ";}  else if(which=="egcfrat2"){document.f.cf.value="4,3,[1,2]";clearxcpt('cf'); pushme(document.cfLbtn);document.ans.morecf.value=" ";}  else if(which=="egeval1"){document.f.dec.value="3*4.5 - 7.6/8";clearxcpt('dec');pushme(document.decRbtn)}  else if(which=="egeval2"){document.f.dec.value="pow((sqrt(5)+1)/2,3)";clearxcpt('dec');pushme(document.decRbtn)}  else if(which=="egeval3"){document.f.dec.value="cos(Pi*36/180)";clearxcpt('dec');pushme(document.decRbtn)}  };function clearxcpt(fld){    if(arguments.length==0)fld="";  eval(btnoff);  if(fld!='cf')   {document.f.cf.value=" ";document.ans.morecf.value=" "; Cf.reset();};  if(fld!="dec")  {document.f.dec.value=""}  if(fld!="fract"){setRNS("","","")}};  var btnoff="";function pushme(wh){ //alert(wh.name+" "+wh.src);  if(endswith(wh.src,"HiLite.gif"))          {wh.src= wh.src.replace(/HiLite/,'');btnoff=""}  else    {wh.src= wh.src.replace(/\.gif/,"HiLite.gif");btnoff="pushme(document."+wh.name+")"} ;};  function dogcd(){  if(document.f.g1.value=="")return;  if(document.f.g2.value=="")return;  document.f.gcd12.value=gcd(document.f.g1.value,document.f.g2.value)};function dps(r,d){  var x= (Math.floor(r*Math.pow(10,d))/Math.pow(10,d)).toString();   for(var i=1;x.length-x.indexOf(".")-1<d;i++)x+="0"; return x }  function bestRATS(real){ /* find best rational approximations */  if(arguments.length==0){real=document.f.dec.value}  var maxd=4;  //alert(real);  var err=real,t,b,bestt,bestb,approxs=new Array(),maxb=Math.pow(10,maxd);  bestt=Math.round(real),bestb=1;approxs[1]=new RAT(bestt,bestb),err;  document.ans.Recordtxt.value+="\r"+real+" is approximated best by:";  for(var b=2;b<=maxb;b++)  {  t=Math.round(b*real);     if(Math.abs(real-bestt/bestb)>Math.abs(real-t/b))        {bestt=t;bestb=b;approxs[approxs.length]=new RAT(t,b)         rat2cf(t,b);         err=eval(t/b)-real;         document.ans.Recordtxt.value+="\r"+dps(eval(t/b),maxd+3)+"="+t+"/"+b+"="+Cf.cftoString()+" err="+err}  };  document.ans.Recordtxt.value+="\r";  return approxs };