var globalversion="28Aug07";//alert(globalversion);function halt(msg){alert(msg+" [ref="+refNB+"]");ERROR()};//   ----------- CONSTANTS and LITERALS -------------var ERR=0.0006; //3 dps  not 0.005 for rounding of 0.xxx5function DBGeval(s){dbg=true;var x=eval(s);dbg=false;return x};var  dbg=false,   minusch="&ndash;"  ,times="&times;"  ,imagj=" <span class='imag'>j</span>"  ,imagJ=" <span class='imag'>J</span>"  ,imagi=" <span class='imag'>i</span>"  ,imagI=" <span class='imag'>I</span>"  ,integch="<img src='integ.gif' width=10 height=27 alt='integrate'>"  //&int;  &#8747;  ,alpha="<i>&alpha;</i>"    //"<img src='alpha.gif' width=10 height=8 alt='alpha'>" //"&alpha;" //&#945;   ,beta="<i>&beta;</i>"  //&#946;  ,gamma="<i>&gamma;</i>"  //&#947;  ,delta="<i>&delta;</i>"  //&#948;  ,lambda="<img src='lambda.gif' style='width:0.8em; height:0.8em' alt='lambda'>"  //"&lambda;"   ,theta="&theta;" //&#952;  ,pi="<i>&pi;</i>"       //"<img src='pi.gif' width=16 height=13 alt='pi'>"   //&#960;  ,phi="<i>&phi;</i>"     //&#966;  ,Sigma="&8721;"  // same as Sum  ,E="<b>e</b>"  ,rarrow="<img src='rarrow.gif' width=18 height=10 hspace=0 vspace=0 border=0 alt='->'>"  ,implies="<img src='implies.gif'  alt='=>'>" //"&#8658;"  // "&rArr; "    ,impliedbych="<img src='impliedby.gif'  alt='<='>" //  //"&#8656;"   "&lArr; "  ,iffch="<img src='iff.gif'  alt='<=>'>"    // //"&#8660;" "&hArr; "  ,Prod="&#8719;"  //&prod;  ,Sum="&#8721;"    //&sum;  ,oBKT="<span class=bkts2>(</span>" //"<img src='open.gif'  height:'100%' alt='('>" --not Opera!   //"<img src='obkt.gif' height:'100%' alt='('>"    //  //should be height='100%'  ,cBKT="<span class=bkts2>)</span>" // "<img src='cbkt.gif' height:'100%'   alt=')'>" //"<img src='close.gif' style='width:1em; height:100%' alt=')'>"//  // //should be height='100%'  ,obkt="("  ,cbkt=")"  ;var root2=Math.sqrt(2);var minusch2=" "+minusch+" ",iff=iffch;//   --------------- URL PARAMETERS ----------function getArgs(opts){  if(arguments.length==0)opts=location.search.substring(1);  //alert("getArgs "+opts);  var args=new Object();  var pairs=opts.split(",");  //if(pairs.length>0)alert("getArgs "+pairs);  for(var i=0;i<pairs.length;i++)  { var pos=pairs[i].indexOf("=");	if(pos==-1)args[pairs[i]]=true  //allow ids with no values	else args[pairs[i].substring(0,pos)]=pairs[i].substring(pos+1);   };   return args };var refNB= Math.floor(Math.random()*100000);   var args=getArgs();if(args.ref)refNB=parseInt(args.ref);var  seed=refNB;  //a randomly generated test is the defaultargs.fileURL=location.toString().slice(location.toString().lastIndexOf("/")+1).replace("#","");args.fileURL=(args.fileURL.indexOf("?")==-1?args.fileURL:args.fileURL.slice(0,args.fileURL.indexOf("?")));args.ref=refNB.toString();args.fileQuRefURL=args.fileURL+"?ref="+args.ref+(args.qu?",qu="+args.qu:"");args.fileQuURL=args.fileURL+(args.qu?"?qu="+args.qu:"");args.filename=args.fileURL.replace(".html","");function gotoURL(url){  window.location.href=url};var imag=(args.imag && (args.imag.toLowerCase()=="i"||args.imag.toLowerCase()=="j")?eval("imag"+args.imag):imagj);function arrayindex(x,arr){   for(var i=0;i<arr.length;i++)if(arr[i]==x)return i;  return -1};function checkqu(elts,defalt){// alts is an ARRAY of string alernatives of question types  if(arguments.length<2)defalt=randelt(elts);  if(args.qu)    {if(arrayindex(args.qu,elts)==-1)halt("There is no question of the type "+args.qu+": use one of "+elts.join(','));     return args.qu}  else return defalt};   // ------- RANDOMISERS ------- function RND(){ seed=seed*Math.PI+root2; seed=seed-Math.floor(seed);    //if(!confirm(seed))HALT();    return seed};function randint(lo,hi){ lo=eval(lo);hi=eval(hi);  if(lo>hi)alert("randint error: lo exceeds hi! "+lo+","+hi)  else {do{var r=Math.floor(RND()*(hi-lo+1))+lo;}        while(r>hi);  //random can return 1.00!!        //alert("randint("+lo+","+hi+")="+r);        return r}      };function randintx(lo,hi,xcpts){  do{var x=randint(lo,hi);     var xcpt=false;     for(var i=0;i<xcpts.length&&!xcpt;i++)xcpt=xcpts[i]==x;    }while(xcpt);  return x};function randintnz(lo,hi){return randintx(lo,hi,[0])};function randbool(){return randint(0,1)==0};function randnorm(mean,sd){  return Math.sqrt(-2*Math.log(RND()))*Math.cos(2*Math.PI*RND())*sd+mean};function randelt(vals){   if(arguments.length==1)      {if(typeof vals=="object")return vals[randint(0,vals.length-1)]       else if(typeof vals == "string")return randelt(vals.split(""));      }   else return arguments[randint(0,arguments.length-1)]};function 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 permuteBetween(from,to){  var p=new Array(to-from+1); var q=new Array(to-from+1);  for(var i=0;i<q.length; i++)  q[i]=from+i;  for(var i=0;i<p.length; i++,q.length--)     {var j=randint(0,q.length-1);   p[i]=q[j];  q[j]=q[q.length-1]     }  return p};function randelts(elts,n){ //alert(">randelts< "+elts+" "+n);  var e=permuteBetween(0,elts.length-1);  var res=new Array(n);  for(var i=0;i<n;i++)res[i]=elts[e[i]];  return res};function randints(lo,hi,n){var e=permuteBetween(lo,hi);return e.slice(0,n)};  function zip(as,bs){var z=new Array(Math.min(as.length,bs.length)); for(var i=0;i<as.length && i<bs.length;i++)z[i]=new Array(as[i],bs[i]); return z};function unzip(abs){var as=new Array(abs.length),bs=new Array(abs.length);  for(var i=0;i<abs.length;i++){as[i]=abs[i][0];bs[i]=abs[i][1]};  return [as,bs]};function freqs(arr){/* access result as freqs(arr)[arr[i].toString()] */  var elts=new Object();  if(typeof arr == "string")arr=arr.split("");  for(var i=0;i<arr.length;i++)    elts[arr[i].toString()]=1+(elts[arr[i].toString()]?elts[arr[i].toString()]:0);  return elts}  function numorderINCR(a,b){return a-b};  /* arg to Array.sort() for numeric arrays... */function log10(x){return Math.log(x)*Math.LOG10E};var primesknown =[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];var pyth=new Array([3,4,5],[6,8,10],[5,12,13],[9,12,15],[8,15,17],[12,16,20],  [15,20,25],[7,24,25],  [10,24,26],[20,21,29],[18,24,30],[16,30,34],[21,28,35],[12,35,37],[15,36,39],    [24,32,40],[14,48,50]);function isknownprime(p){  var lo=0; var hi=primesknown.length-1; var state='unknown';  if(p>primesknown[hi]){halt("isknownprime called outside known range");return};  while(state=='unknown' && lo<=hi)  {  var mid=Math.floor((lo+hi)/2);     if(p<primesknown[mid])hi=mid-1     else if(p==primesknown[mid])state= 'prime'     else lo=mid+1  };  return state=='prime'};function factors(n){  if(n>Math.pow(primesknown[primesknown.length-1],2))halt("Cannot factor "+n+" - too large!");  if(n<0)n=-n;  if(isknownprime(n))return [n];  var maxp=Math.floor(Math.sqrt(n)+0.001), maxI=primesknown.length-1;  //if(maxp>lastknownprime){halt("factorsOf cannot use primes beyond those known");return};  var fs=[]; var i=0;  while(i<=maxI && primesknown[i]<=Math.sqrt(n))  {  if(n%primesknown[i]==0)         {fs=fs.concat(primesknown[i]);          n=Math.round(n/primesknown[i]);          if(isknownprime(n))return fs}     else i++ };  return fs.concat(n);//  i=lastknownprime+2;//  while(i<=Math.sqrt(n))//  {if(n%i==0){fs=fs.concat(i);n=Math.round(n/i);if(is1prime(n))return fs}else{i+=2}};//  return fs.concat(n)};function factorpairs(n){var p=new Array();  if(n<0)n=-n;  for(i=1;i<=Math.sqrt(n);i++) if(n%i==0)p[p.length]=new Array(i,Math.round(n/i));  //alert("factorpairs of "+n+"="+p+" ");  return p};function showfactorpairs(n){ var ps=factorpairs(n);  for(var i=0;i<ps.length;i++)ps[i]=ps[i][0]+"&times;"+ps[i][1];  return "<span class='poly'>"+(ps.length>2?ps.slice(0,ps.length-1).join(", "):ps[0])        +(ps.length>1?"</span> and <span class='poly'>"+ps[ps.length-1]:"")+"</span>"}function issq(n){ return isFinite(n) && (n>=0) && Math.pow(Math.round(Math.sqrt(n)),2)==n};// ------------  --------------var maxdps=Math.PI.toString().length-2;function nbdps(n){   //if(n.indexOf('e')==-1) return n.length-n.indexOf(".")-1   n=(typeof n=="number"?n:eval(n)).toString();   if(n.indexOf("e")!=-1 && n.indexOf(".")==-1)n=n.replace("e",".0e");   if(isZ(n))return 0;   if(n.toString().indexOf(".")==-1)return 0;   //alert(n.substring(n.indexOf("e")+1));   var res=n.indexOf("e")==-1           ?n.length-n.indexOf(".")-1           :n.indexOf("e")-n.indexOf(".")-1-n.substring(n.indexOf("e")+1);   return (res<0?0:res);};function dps(num, d,Cond) { //Cond: "s"suppress trailing 0 "x"=debug   var IN=num;    if(arguments.length==1)d=5;   if(arguments.length<3)Cond="";  // document.f.res.value +=num+" <> "+d+(Cond==""?"":Cond);   //default here is 4dps -- return num, rounded to exactly d    if(arguments.length<2)d=5;    //Cond includes: "s"=short=no trailing 0s;    if(isQ(num))num=num.val;   // var a=(typeof num!="number"?eval(num):num).toFixed(d).toString();alert("dps "+num+" "+d+"="+a);   if(typeof d=="string")d=eval(d);    var a=num;   if(!isFinite(num)){return num}   else {if(num<0){var SGN="-";a=-num}else{SGN=""}; //ASSERT num>=0         if(a.toString().indexOf(".")!=-1)            {a=a.toString();             while(a.charAt(a.length-1)=="0" && nbdps(a)>d)a=a.slice(0,a.length-1);             //if(dbg)alert("has. num0="+a+" nbdps="+nbdps(a));            };         a=a.toString();         if(a.indexOf("e")!=-1&&a.indexOf(".")==-1)a=a.replace("e",".0e");         //if(dbg)alert("donee a="+a+" nbdps="+nbdps(a));         if(isZ(a) || d>=maxdps ){a=a.toString()}         else if(d>=nbdps(a))              { if(a.indexOf("e")==-1){//not correct!                   //if(dbg)alert("?? "+a+" has "+nbdps(a)+" dps");                  while(a.length-a.indexOf(".")-1<d)a=a.concat("0")}}         else {var n= Math.pow(10, d);               //if(dbg)alert(n+" round to "+Math.round(a*n));			   a= (Math.round(a*n) / n).toString();  //AAGH! Safari produces a maxint value for all flaots bigger than it!!			   //if(dbg)alert("raw rounded is"+a+" nbdps="+nbdps(a)+" has.at="+a.indexOf('.'));			   if(a.indexOf(".")==-1)a=a.concat(".");			   if(nbdps(a)<d)while(a.length-a.indexOf(".")-1<d)a=a.concat("0")			   //if(dbg)alert(" rnds to  "+a);			   if(a.charAt(0)==".")a="0"+a;		}    }   //if(dbg)alert("dps("+IN+","+d+","+Cond+")="+a);   if(Cond.indexOf("s")!=-1 && a.indexOf(".")!=-1 && a.indexOf("e")==-1)         {var i=a.length-1;          while(a.charAt(i)=="0")i--;           if(a.charAt(i)==".")i--;          a=a.substr(0,i+1);          if(a.charAt(i)==".")a.concat("0");          };   if(a.charAt(0)==".")a="0"+a;   if(a==""){a="0";if(SGN!="")SGN=""};   return (a!=0?SGN+a:a)};function nth(n,typ){ if(arguments.length==1)typ="th";     var s="";     var digits=["zero","one","two","three","four","five","six","seven","eight","nine"],         digths=["zeroth","first","second","third","fourth","fifth","sixth","seventh","eighth","ninth"],         tens=["","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"],         tenths=["","tenth","twentieth","thirtieth","fortieth","fiftieth","sixtieth","seventieth","eightieth","nintieth"]        teens=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],        teenths=["tenth","eleventh","twelfth","thirteenth","fourteenth","fifteenth","sixteenth","seventeenth","eigthteenth",           "nineteenth"];   var h=Math.floor((n%1000)/100),t=Math.floor((n%100)/10),u=n%10;   if(n>=1000 || typ=="th") return n+(typ=="words"?"":"<sup>"+(t==1?"th":n%10==1?"st":n%10==2?"nd":n%10==3?"rd":"th")+"</sup>");   if(h>0)s=digits[h]+" hundred"+(typ=="th"&&t==0&&u==0?"th":"");   if(t>0){if(s!="")s+=" and ";                if(t==1&&u!=0)return s+(typ=="th"?teenths[u]:teens[u])           else if(u==0)return s+(typ=="th"?tenths[t]:tens[t])           else //u!=0&&t>1                s+=tens[t]          };   if(h>0&&u>0&&t==0)s+=" and ";   if(u>0)s=s+(s!=""?(t>1&&u!=0?"-":" "):"")+(typ=="th"?digths[u]:digits[u])   return (n==0?(typ=="th"?"zeroth":"zero"):s)};function numberword(n){return nth(n,"words")};    function gcd(a,b){var g;  if(arguments.length==1)    {g=gcd1(a[0],a[1]);      for(var i=2;g>1&&i<a.length;i++)g=gcd1(g,a[i]);   }else{      g=gcd1(arguments[0],arguments[1]);      for(var i=2;g>1&&i<arguments.length;i++)g=gcd1(g,arguments[i]);  };  return g}; function gcd1(a,b){    a=Math.abs(a);   b=Math.abs(b);   while(a>0 && b>0){var aa=a;a=b%a;b=aa};   return (a==0?b:a) };function solvegcd(aa,bb){var ab,L;   if(aa<0||bb<0)      {ab=solvegcd(Math.abs(aa),Math.abs(bb))       if(aa<0)ab[0]=-ab[0];       if(bb<0)ab[1]=-ab[1];       //document.writeln("--GCD(",aa,",",bb,")=",ab[0],"*",aa,"+",ab[1],"*",bb,"<br>");       return ab;      };   if(aa>bb){ab=solvegcd(bb,aa);             //document.writeln("sGCD(",aa,",",bb,")=",ab[1],"*",aa,"+",ab[0],"*",bb,"<br>");    ;return [ab[1],ab[0]]};      ab=new Array();L=-1;   ab[++L]=[0,1];ab[++L]=[1,0];  //a1*a+b1*b   var a=aa,b=bb;   while(b>0){var q=Math.floor(b/a),r=b%a;// b=qa+r          L++;         ab[L]=new Array(ab[L-2][0]-q*ab[L-1][0],ab[L-2][1]-q*ab[L-1][1]);         //document.writeln(b,"=",q,"*",a,"+",r,": ",r," = ",ab[L][0],"*",aa," + ",ab[L][1],"*",bb,"<br>");         b=a;a=r;          };   // document.writeln("*GCD(",aa,",",bb,")=",ab[L-2][0],"*",aa,"+",ab[L-2][1],"*",bb,"<br>");    return ab[L-2]; };function lcm(a,b){if(a<0)a=-a;if(b<0)b=-b;return Math.round(a/gcd(a,b))*b};function Fac(n){var r=1;for(var  i=2;i<=n;i++)r*=i;return r};function nCr(n,r){  function Fac2(n,m){//Fac(n)/Fac(m)       var r=1;for(var i=m+1;i<=n;i++)r*=i; return r};  if(r>n || r<0 || n<0)return 0  else return (r<n/2 ? Fac2(n,n-r)/Fac(r) : Fac2(n,r)/Fac(n-r))};function RAT(t,b){  // if infinite, sets  t=1 and b=0  if(!isZ(t))halt("Cant make Q from num:"+t);  if(!isZ(b))halt("cant make Q from den:"+b);  if(b==0){t=(t>0?1:-1)}  else{var g=gcd(t,b);if(g>1){t=Math.round(t/g);b=Math.round(b/g)}};  if(b<0){t=-t;b=-b}  this.top=NB(t);  this.bot=NB(b);  this.isfinite=b!=0;  this.toString=function(){      return (this.isfinite?(this.bot==1?this.top.toString()                                        :this.top.toString()+"/"+this.bot.toString()+"")                           :(this.top<0?"-":"")+"Infinity")};  this.val=NB(t/b);  this.sgnum=(this.top<0?-1:this.top==0?0:1);};function RATmul(a,b){if(typeof a=="number")a=new RAT(a,1);if(typeof b =="number")b=new RAT(b,1);   return new RAT(a.top*b.top,a.bot*b.bot)};function RATdiv(a,b){if(typeof a=="number")a=new RAT(a,1);if(typeof b =="number")b=new RAT(b,1);   return new RAT(a.top*b.bot,a.bot*b.top)};function RATadd(a,b){if(typeof a=="number")a=new RAT(a,1);if(typeof b =="number")b=new RAT(b,1);   return new RAT(a.top*b.bot+b.top*a.bot,a.bot*b.bot)};function RATsub(a,b){if(typeof a=="number")a=new RAT(a,1);if(typeof b=="number")b=new RAT(b,1);   return RATadd(a,RATneg(b))};function RATneg(a){return (typeof a=="number"?new RAT(-a,1):new RAT(-a.top,a.bot))};function RATis(a,op,b){if(typeof a=="number")a=new RAT(a,1);if(typeof b=="number")b=new RAT(b,1);     var L=a.top*b.bot,R=a.bot*b.top;     return eval(isFinite(L)&&isFinite(R)?L+op+R:a.val+op+b.val)};function showRAT(r,sty){if(arguments.length==1)sty="polysmall"; return frac(r.top,r.bot,sty)};function qnb(n,styl){if(arguments.length==1)styl="";   return (styl==""?"":"<span class='"+styl+"'>")+dps(n).toString().replace(/-/,minusch)+(styl==""?"":"</span>")};function showNB(n,sty){   if(arguments.length==1)sty=(isQ(n)?"polysmall":"poly");  if(isC(n))return showterms([[Cre(n),1],[Cim(n),imag]])  if(isQ(n)) return showRAT(n) ;  if(isInfinite(n))return spn((cmp(n,"<",0)?minusch:"")+"Infinity",sty);  if(isZ(n))return spn(n,sty);  if(isR(n))return showterms([[dps(n,3,"s"),1]]);};var toosmall=0.0000000001,toolarge=100000;function NB(x){if(Math.abs(Math.round(x)-x)<=toosmall)return Math.round(x)    else if(x>toolarge)return Number.POSITIVE_INFINITY    else if(x<-toolarge)return Number.NEGATIVE_INFINITY    else return x};function norm(x){   if(isPOLY(x)&&x.deg==0){x=POLYcoeff(x,0)};   if(isC(x)&&NB(Cim(x))==0){x=Cre(x)};   if(isQ(x)&&x.bot==1){x=x.top};   if(isR(x)&&Math.abs(Math.round(x)-x)<toosmall)x=Math.round(x);   return x};function Z2Q(n){return new RAT(n,1)};function Q2C(r){return new COMPLX(r,0)};function Q2R(x){return x.val};function R2C(x){return new COMPLX(x,0)};function isZ(x){return !isNaN(x) && isFinite(x) &&  x.toString().indexOf(".")==-1};function isR(x){return !isNaN(x) && isFinite(x) && x.toString().indexOf(".")!=-1};function isNb(x){return isZ(x)||isR(x)};function isQ(x){return typeof x=="object" && x.top};   //x instanceof RAT }  function isC(x){return typeof x=="object" && x.im};   //x instanceof COMPLX};function isfinite(n){return isQ(n)? n.isfinite:isFinite(n)};function isInfinite(x){return isQ(x)&&!x.isfinite || !isC(x) &&!isfinite(x)};var notyp="?no-type?"function typ(x){return isZ(x)?"Z":isR(x)?"R":isQ(x)?"Q":isC(x)?"C":isPOLY(x)?"P":notyp};function isString(s){return typeof s == "string"};function toR(x){return isC(x)?x:isQ(x)?x.val:isR(x)||isZ(x)?x:halt("cannot convert "+x+" to R")};function toC(x){if(typ(x)=="C"){return x }else{ return [x,0]}};function toQ(x){switch(typ(x)){   case "Q":return x;   case "C":halt("Cant convert CtoQ "+C);   case "R":halt("Cant convert RtoQ "+x);   case "Z":return Z2Q(x);}};function toR(x){     if(isQ(x))return x.val;     if(isC(x)){if(x[1]==0){return x[0]}else{halt("Cant convert CtoR:"+x)}};     if(isNb(x))return x;     };function add(x,y){//document.writeln(">>> ",typeof x,"=",x,"  ",typeof y,"=",y);        if(isInfinite(x) && isInfinite(y)) return (cmp(x,">",0)==cmp(y,">",0)?x:Number.NaN)   else if(isInfinite(x))return x   else if(isInfinite(y))return y   else if(isR(x)||isR(y))return norm(toR(x)+toR(y))   else if(isQ(x)||isQ(y)){x=toQ(x);y=toQ(y);return norm(RATadd(x,y))};   return norm(NB(eval(x)+eval(y))); };function sub(x,y){return add(x,neg(y))};function neg(x){ if(isNb(x))return -x;   if(isInfinite(x))return -x;   if(isQ(x))return RATneg(x);   halt("??? negate "+x)};function mul(a,b){        if(isInfinite(a))return (b==0?Number.NaN:cmp(b,">",0)?a:-a)   else if(isInfinite(b))return (a==0?Number.NaN:cmp(a,">",0)?b:-b)   else if(isC(a)||isC(b)){a=toC(a);b=toC(b);return norm(Cmul(a,b))}   else if(isR(a)||isR(b))return norm(toR(a)*toR(b));   else if(isQ(a)||isQ(b)){a=toQ(a);b=toQ(b);return norm(RATmul(a,b))}   return norm(a*b)};function mod(a,b){  if(isInfinite(b))return (!isInfinite(a)?a:Number.NaN);  if(isZ(a)&&isZ(b))return a%b  return Number.NaN};function div(n,d){//alert("div "+typ(n)+" "+typ(d));   if(isR(n)||isR(d)){n=toR(n);d=toR(d);return norm(NB(n/d))};   //alert(n+" mod "+d+" = "+mod(n,d)+" flr="+Math.floor(n/d));   if(isZ(n)&&isZ(d))       if(mod(n,d)==0)return norm(Math.round(n/d))       else return norm(new RAT(n,d));   n=toQ(n);d=toQ(d);return norm(RATdiv(n,d))};function pow(a,b){//alert("pow "+typ(a)+"^"+typ(b));  if(isQ(b))b=b.val;  if(isQ(a)){             if(isZ(b)&&b<0)return new RAT(Math.pow(a.bot,-b),Math.pow(a.top,-b))             else           return new RAT(Math.pow(a.top,b),Math.pow(a.bot,b))};  a=toR(a);return norm(NB(Math.pow(a,b)))};function cmp(a,op,b){   if(op=="=")op="==";  if(isQ(a)||isQ(b)){a=toQ(a);b=toQ(b);return RATis(a,op,b)};   return eval(a+op+b)};function abs(x){if(cmp(x,"<",0))x=neg(x);return x};function num(n){ return isQ(n)?n.top:n };function den(n){return isQ(n)?n.bot:1};// ------------------ NUMBER TYPES ------------function POLY(cofs){var d=cofs.length-1;    for(var i=0;i<=d;i++)cofs[i]=norm(cofs[i]);    while(cofs[d]==0&&d>0)d--;this.deg=d;this.c=cofs.slice(0,d+1);    this.toString=function(){var s="";          for(var i=0;i<=this.deg;i++)s=cofs[i]+"x^"+i+(s!=""?",":"")+s;         return s}    };function isPOLY(P){return  P.deg>=0};        //P instanceof POLY};var POLY0=new POLY([0]), POLY1=new POLY([1]);function POLYz(p){var m=1;for(var i=0;i<=p.deg;i++)if(isQ(p.c[i]))m=lcm(m,p.c[i].bot);  return (m>1?POLYmul(new POLY([m]),p):p)};function POLYcoeff(p,i){return i<0||i>p.deg?0:p.c[i] };function POLYcval(p,i){var c=POLYcoeff(p,i);return isQ(c)?c.val:c};function POLYdeg(p){return p.deg};function POLYcoeffstr(p){return "<"+p.c.join(",")+">"};function POLYval(p,v){var res=0;for(var i=0;i<=p.deg;i++)res=add(res,mul(pow(v,i),p.c[i]));return res};function POLYadd(p1,p2){var s=new Array();   if(isNb(p1)||isQ(p1))p1=new POLY([p1]);  if(isNb(p2)||isQ(p2))p2=new POLY([p2]);   for(var i=0;i<=Math.max(p1.deg,p2.deg)+1;i++)      {s[i]=add(POLYcoeff(p1,i),POLYcoeff(p2,i));};   return new POLY(s)};function POLYneg(p){var s=new Array(p.deg+1);for(var i=0;i<=p.deg;i++)s[i]=neg(p.c[i]);return new POLY(s)};function POLYsub(p1,p2){if(isNb(p1)||isQ(p1))p1=new POLY([p1]);  if(isNb(p2)||isQ(p2))p2=new POLY([p2]);   return POLYadd(p1,POLYneg(p2))};function POLYgcd(p){var g=POLYcoeff(p,0);if(isQ(g))g=1;  for(var i=1;i<=p.deg;i++)if(isZ(POLYcoeff(p,i)))g=gcd(g,POLYcoeff(p,i));  return g };function POLYmul(p1,p2){var s=new Array();  if(isNb(p1)||isQ(p1))p1=new POLY([p1]);  if(isNb(p2)||isQ(p2))p2=new POLY([p2]);  for(var i=0;i<=p1.deg+p2.deg+1;i++)s[i]=0;  for(var i=0;i<=p1.deg;i++)for(var j=0;j<=p2.deg;j++)s[i+j] =add(s[i+j],mul(p1.c[i],p2.c[j]));  return new POLY(s)};function POLYdivk(p,k){return POLYmul(p,new POLY([new RAT(1,k)]))};function POLYpow(p1,n){if(!isZ(n) ||n<0)halt("!! cannot compute POLY to non-posint power !!");  var p=new POLY([1]);  for(var i=1;i<=n;i++)p=POLYmul(p,p1);  return p};function POLYof(p,q){//alert(POLYcoeffstr(p)+" ("+POLYcoeffstr(q)+")");  var r=new POLY([0]);for(var i=0;i<=p.deg;i++)r=POLYadd(r,POLYmul(POLYpow(q,i),new POLY([p.c[i]])));  return r};function POLYdiff(p){  var c=new Array(p.deg-1);for(var i=1;i<=p.deg;i++)c[i-1]=RATmul(i,POLYcoeff(p,i));return new POLY(c)};function POLYeq(p,q){   if(p.deg!=q.deg)return false;   for(var i=0;i<=p.deg;i++)if(cmp(POLYcoeff(p,i),"!=",POLYcoeff(q,i)))return false;   return true};function showPOLYq(p,v,opts){ //pPOLY p has coeff(s) in Q  //if(dbg)alert("showPOLYq "+p.c+" of "+v+" "+opts);  if(arguments.length==1)v='x';  var args=(arguments.length==3?getArgs(opts):new Object());  if(p.deg==0){return showNB(POLYcoeff(p),0)};  var s="",first=true,sgn;   for(var i=(args.rev?0:p.deg);(args.rev?i<=p.deg:i>=0);(args.rev?i++:i--)){     if(equals(POLYcoeff(p,i),0))continue;     sgn=cmp(POLYcoeff(p,i),'>',0)?"+":minusch;     if(first && sgn=="+")sgn="";     if(isQ(p.c[i]))s+=(sgn=="+"?"<td class=poly>"+sgn+"</td>":"")+                    (p.c[i].val==1 && i>0                    ?""                    :"<td>"+frac(p.c[i].top,p.c[i].bot,"polysmall")+"</td>"                    ) +(i>0?"<td valign=middle class=poly>"+(isVar(v)?Var(v):v)+(i>1?"<sup>"+i+"</sup>":"")+"</td>":"")     else {s+="<td class=poly>"+showcoeff3(p.c[i],(i>0?v:1),i,!first)+"</td>"};     first=false;   }  return "<table "+(args.inline?"style='display:inline'":"")+"><tr>"+s+"</tr></table>"};function isPOLYQ(p){  var hasQ=false;  for(var i=p.deg;i>=0;i--)if(isQ(p.c[i]))hasQ=true;  return hasQ};function showPOLY(p,vr,opts){  if(arguments.length==1)vr='x';  if(arguments.length<3)opts="";  if(!isPOLY(p)){halt("showPOLY was given typ "+typ(p))};  var args=getArgs(opts);  if(isPOLYQ(p))return showPOLYq(p,vr,opts);  //if(dbg)alert("showPOLY "+p.c+" of "+vr+" "+opts)  var s= new Array(),hasQ=false;  for(var i=p.deg;i>=0;i--){     s[(args.rev?i:p.deg-i)]=[p.c[i],(i==0?"1":vr),i];    };  //if(dbg)alert("showP "+s);  return showterms(s,"inspan")};function toZPOLYf(p){var l=1,c;if(p.deg==0&&POLYcoeff(p,0)==0)return 1;    for(var i=0;i<=POLYdeg(p);i++){c=POLYcoeff(p,i);if(isQ(c))l=lcm(l,den(c))};return l};function toZPOLY(p){ return POLYmul(p,toZPOLYf(p))};function POLYzfac(p){var f=0;if(p.deg==0&&POLYcoeff(p,0)==00)return 1;   for(var i=0;i<=p.deg;i++)f=gcd(f,POLYcoeff(p,i));   return f};//function POLYstr(p){}var RoundERR=0.0000000001;function equalFN(nbpts,f1,f2){var maxX=30;  //alert("equalFN "+nbpts); // must agree at nbpts non-infinite values  var X=0;  var again;if(!isZ(nbpts))halt("equalFN needs nb as arg1");  if(typeof f1 != "function")halt("equalFN needs arg 1 function");  if(typeof f2 != "function")halt("equalFN needs arg 2 function");  for(var n=0;n<nbpts&&X<maxX;n++)  {  do{X++;        var a=f1(X),b=f2(X);if(isQ(a))a=toR(a);if(isQ(b))b=toR(b);        if(isNaN(a)||isNaN(b)){//alert(a+" ? "+b);            again=true}        else {again=false;             if(Math.abs(a-b)>=RoundERR)              {//alert(n+" try "+X+"@"+X+" FAILS: "+a+" != "+b);               return false}             }               }while(again&&X<maxX)   }    //alert("equalFN ok on "+n+", tried "+X);   return n==nbpts }; // ------------------ COMPLEX NUMBERS ----------------function COMPLX(xr,yt,which){  if(arguments.length==2)which="cart";  if(which=="cart"||which=="polar")which="coords="+which;  var OPTS=getArgs(which);  if(typ(xr)==notyp||typ(yt)==notyp)halt("?? COMPLX was given a non-number");   switch(OPTS.coords){  case "polar":    this.r=xr;    this.angunit=(OPTS.angunit?OPTS.angunit:"radians");    this.theta=normAng(yt,this.angunit);        this.x=this.r*Math.cos((this.angunit=="radians"?this.theta:degtorad(this.theta)));     this.y=this.r*Math.sin((this.angunit=="radians"?this.theta:degtorad(this.theta)));    break;  case "cart":      this.x=xr;      this.y=yt;      this.r=Math.sqrt(Math.pow(this.x,2)+Math.pow(this.y,2));      var aQ1=Math.atan(Math.abs(this.y/this.x));      this.theta=            (this.x==0?(this.y>0?Math.PI/2:this.y==0?Number.NaN:-Math.PI/2)            :this.x<0?(this.y<0?-Math.PI+aQ1:Math.PI-aQ1)            :         (this.y<0?-aQ1:aQ1)            );break;  };  this.re=this.x;  this.im=this.y;  this.toString=function(){return showterms([[this.x,1],[this.y,imag]])    .replace("<span class='poly'>","")    .replace(/<\/span>/g,"").replace(/<span class='imag'>/g,"").replace(/\&ndash;/g,"-")    .replace(/ /g,"")    };  this.showxy=function(d,opts){if(arguments.length<1)d=3;if(arguments.length<2)opts="s";     return showterms([[dps(this.x,d,opts),1],[dps(this.y,d,opts),imag]])};  };function Cre(c){return (typ(c)=="C"?c.x:c)};var Cx=Cre,Cy=Cim;function Cim(c){return (typ(c)=="C"?c.y:0)};function Cr(c){return (typ(c)=="C"?c.r:c)};function Cmod(c){return (typ(c)== "C"?c.r:c)};function Carg(c){return (typ(c)=="C"?c.theta:void 0)};function Cadd(w,z){ if(isC(w)||isC(z)){return new COMPLX(add(Cre(w),Cre(z)),add(Cim(w),Cim(z)))}; return add(w,z);};function Cneg(w) {return isC(w) ? new COMPLX(neg(Cre(w)),neg(Cim(w)) ): neg(w) };function Csub(w,z){return Cadd(w,Cneg(z))};function Cmul(w,z){//out("Cmul "+w+" "+z);  if(isC(z)||isC(w)){z=toC(z);w=toC(w);return new COMPLX(sub(mul(Cre(w),Cre(z)),mul(Cim(w),Cim(z))),                            add(mul(Cre(w),Cim(z)),mul(Cim(w),Cre(z))))};  return mul(w,z)};function CdivR(w,r){   if(isC(w))return new COMPLX(div(Cre(w),r),div(Cim(w),r));   return div(w,r);};function Cdiv(w,z){//out("Cdiv",w," ",z);   if(isC(w))    {if(isC(z))return CdivR(Cmul(w,Cconj(z)),pow(Cmod(z),2))     else     return new COMPLX(div(Cre(w),z),div(Cim(w),z))    }   if(isC(z))return Cmul(Conj(z),div(w,pow(Cmod(z),2)))   else return div(w,z);};function Cconj(w){return isC(w) ? new COMPLX(Cre(w),neg(Cim(w))) : w};function Cpow(w,p){//p is a Z|R|Q    if(isQ(p))p=p.val;     //out(w+"^"+p+" mod="+Cmod(w)+" arg="+Carg(w));    if(isNb(w))return NB(Math.pow(w,p));    var r=Cmod(w),a=Carg(w);      return new COMPLX(NB(Math.pow(r,p)*Math.cos(a*p)),NB(Math.pow(r,p)*Math.sin(a*p)))};function showCOMPLX(c){return c.showxy() };function showCOMPLX2(c){return showterms([[dps(norm(c.x),3),1],(c.y>=0?" + ":"")])+showterms([[dps(norm(c.y),3),1],imag])};function showrcs(R,T,angunit,ifang){ // show R(cos(T)+sin(T)j)  if(arguments.length==1){T=R.theta;angunit=R.angunit;R=R.r}  else if(arguments.length<3)angunit="d";  if(arguments.length<4)ifang="v";  if(!isNb(R)||!isNb(T)||!isNiceAng(T,angunit)||ifang.charAt(0)=="a")    return onelinemid([(isNb(R)?(R!=1?showNB(R):""):spn(Var(R))),     showterms([(isNb(R)&&R!=1?"(":"")," cos",(isNb(T)&&T<0?"(":" "),(isNb(T)?[T,1]:T),(ifang.charAt(1)=="d"?"&deg;":""),      (isNb(T)&&T<0?")":""),      " + ",imag," sin",(isNb(T)&&T<0?"(":" "),(isNb(T)?[T,1]:T),(ifang.charAt(1)=="d"?"&deg;":""),      (isNb(T)&&T<0?")":""),      (isNb(R)&&R!=1?" )":"")])     ]);  if(equals(R,0))return showNB(0);  if(cmp(R,'<',0))halt('!!! showrcs must have non-negative R:'+R);  var TD=(angunit.charAt(0).toLowerCase()=="d"?T:radtodeg(T)),     hasBra=!cmp(R,'=',1) && (TD%90!=0);      if(TD==0)return showNB(R);  if(TD==180||TD==-180)return showNB(neg(R));  if(TD==90||TD==-90)return showsinD(TD,R,imag);  return onelinemid([(cmp(R,"=",1)?"":showNB(R)),     (hasBra?spn(obkt,"mathl"):""),     showcosD(TD),     (signsinD(TD)>0?spn("+"):""),     (signsinD(TD)!=0?showsinD(TD,1,imag):""),     (hasBra?spn(cbkt,"mathl"):"")     ])};  // -------------------   GEOM -------------function distance(xa,ya,xb,yb){return Math.sqrt(Math.pow(xb-xa,2)+Math.pow(yb-ya,2))};function enBkt(s){return "("+s+")"};function bigbkt(x){return "<span class='larger'>(</span>"+x+"<span class='larger'>)</span>"};function TRI(An,Bn,Cn,A,B,C,a,b,c){   return "<table border=0 width=150 height=150 border=0 cellspacing=0 cellpadding=0 style='background-image:url(tri.gif);'>"  +"<tr height=20><td ></td><td width=60 valign=top><span class=pointname>"+Cn+"</span></td><td width=53></td></tr>"  +"<tr height=30><td></td><td valign=bottom><br>&nbsp;&nbsp;&nbsp;"+C+"</td><td></td></tr>"  +"<tr height=40><td valign=middle align=center>"+b+"&nbsp;</td><td></td>"       +"<td valign=middle align=center>"+a+"</td></tr>"  +"<tr height=30><td></td><td valign=bottom align=left>"+A+"</td><td valign=bottom>"+B+"</td></tr>"  +"<tr valign=bottom height=30><td><span class=pointname>"+An+"</span></td><td align=center>"+c+"</td>"       +"<td align=right><span class=pointname>"+Bn+"</span></td></tr></table>"};function POINT(nm,Coords){      if(arguments.length!=2)halt("new POINT "+nm+", "+Coords+"!!");     if(Coords.length>0){this.x=Coords[0];this.y=Coords[1]};     if(Coords.length>2){this.z=Coords[2]}else{this.z=0};     this.dim=Coords.length;     this.coords=new Array(Coords.length);     for(var i=0;i<Coords.length;i++)this.coords[i]=Coords[i];     this.name=nm;     this.toString=function(){var s="<span class='point'>";        if(this.name!="")s=s+"<span class='pointname'>"+this.name+"</span>";        if(this.dim>0)        {s=s+"(";         for(var i=0;i<this.coords.length;i++)             s=s+showterms([(isVar(this.coords[i])?[1,this.coords[i]]:[dps(this.coords[i],3,"s"),1]),              (i<this.coords.length-1?", ":"")]);         s=s+")"         }         return s+"</span>"       };     this.showname="<span class=pointname>"+this.name+"</span>"};function showPoint(nm,coords){return (new POINT(nm,coords)).toString()};function distancePT2(a,b){return MATH.sqrt(Math.pow(b.y-a.y,2)+Math.pow(b.x-a.x,2)+(a.dim==3?Math.pow(b.z-a.z,2):0))};function distanceExpr2(xa,ya,xb,yb){  return  enBkt(negb(xb)+" &ndash; "+negb(xa))+"<sup>2</sup> + " +    enBkt(negb(yb)+" &ndash; "+negb(ya))+"<sup>2</sup>"};function distancePOINT2(a,b){ return   enBkt(negb(b.x)+" &ndash; "+negb(a.x))+"<sup>2</sup> + " +               enBkt(negb(b.y)+" &ndash; "+negb(a.y))+"<sup>2</sup>"   +(a.dim==3?" + "+enBkt(negb(b.z)+" &ndash; "+negb(a.z))+"<sup>2</sup>":"")};function distanceExpr(xa,ya,xb,yb){return "&radic;( "+distanceExpr2(xa,ya,xb,yb)+" )"};function distancePOINT(a,b){return "&radic;( "+distancePOINT2(a,b)+" )"};function slopeExpr(xa,ya,xb,yb){return Frac("<span class='poly'>"+yb+" &ndash; "+negb(ya)+"</span>",  "<span class='poly'>"+xb+" &ndash; "+negb(xa)+"</span>")};function showPQRline(p,q,r){//var g=gcd(p,q,r);if(g>1){p=p/g;q=q/g;r=r/g};  if(p==0){if(q<0){q=-q;r=-r};return showterms([[q,'x']," = ",[-r,1]])};  if(q==0){if(p<0){p=-p;r=-r};return showterms([[p,'y']," = ",[-r,1]])};  return showterms([[p,'y'],[q,'x'],[r,1]," = ",[0,1]])};function lineZequn(m,c){var l,p,q,r; if(isQ(m)&&m.isfinite||isFinite(m))  {l=lcm(den(c),den(m));p=-l;q=mul(l,m);r=mul(l,c)} else{p=0;q=den(c);r=-num(c)}; if(p<0&&(q<=0||r<=0)||(q<=0&&r<=0)){p=-p;q=-q;r=-r;flip=true}; return [p,q,r]}function NZP(n,z,p){this.nbneg=n;this.nbzero=z;this.nbpos=p};function makeNZP(list){  var n=0,z=0,p=0;  for(var i=0;i<list.length;i++)if(list[i]<0){n++}else if(list[i]==0){z++}else{p++};  return new NZP(n,z,p)};function simplecoeffs(cs){//cs are coefficients of separate vars  var CS=new Array(),chng=false;  var g=gcd(cs);  if(g>1){chng=true;for(var i=0;i<cs.length;i++)CS[i]=cs[i]/g;}  var nzp=makeNZP(cs);  //same signs as CS  //alert([nzp.nbneg,nzp.nbzero,nzp.nbpos]);  if(nzp.nbneg>nzp.nbpos)    {for(var i=0;i<cs.length;i++)CS[i]=-(chng?CS[i]:cs[i]);chng=true};  // alert(cs+">>"+CS);  //alert(cs+chng+CS);  if(chng){return CS}else{return cs};};function sameratio(as,bs){var r,ok=true;//alert(as+"=?="+bs);  if((as[0]!=0&&bs[0]!=0))    {r=as[0]/bs[0]}else{ok= as[0]==bs[0]};  for(var i=1;i<as.length&&ok;i++)ok=equals(r*bs[i],as[i]);  return ok};// ---------- SERIES -------------------function rowAP(a,d,n,styl){if(arguments.length<4)styl=function(i){return ""};  var s="<tr>",t=a;  for(var i=1;i<=n;t=add(t,d),i++)    s=s+"<td>"+(isQ(t)               ?frac(t.top,t.bot,styl(i))               :(styl(i)==""?"":"<span class="+styl(i)+">")+qnb(t)+(styl(i)==""?"":"</span>")               )+"</td>";  s=s+"</tr>";  return s};// ---------  VECTORS MATRICES -----------function scapro(v1,v2){var s=0;for(var i=0;i<v1.length;i++)s=s+v1[i]*v2[i];return s};function showvecname(N){return "<span class='vecname'>"+N+"</span>"};function vecmag(v){var sum=0;for(var i=0;i<v.length;i++)sum=sum+v[i]*v[i]; //document.writeln("<br>vecmag ",v," = &radic; ",sum,"<br>"); return Math.sqrt(sum)};function showposvec(nm){   for(var i=1;i<arguments.length;i++)nm=nm+arguments[i];  return "<table cellspacing=0 cellpadding=0><tr><td>"+rarrow+"</td></tr>"  +"<tr><td class=pointname>"+nm+"</td></tr></table>"};function VECIJ(ij){return "<span class='IJ'>"+ij+"</span>"};function showijvec(v){return showterms([[v[0],VECIJ("i")],[v[1],VECIJ("j")],(v[2]?[v[2],VECIJ('k')]:"")])};function showcolvec(col){ //alert("showcolvec "+col);  var VEC=new Array();   for(var i=0;i<col.length;i++)VEC[i]=[col[i]];   return showmatrix(VEC)};function showvector(arr,typ){ //alert("showvec "+arr+" "+typ);   if(arguments.length==1)typ="col";        if(typ=="col")return showcolvec(arr)   else if(typ=="ij")return showijvec(arr)   else if(typ=="rtheta")return showterms(["(",(isNb(arr[0])?[arr[0],1]:[1,arr[0]]),       ", ",(isNb(arr[1])?[arr[1],1]:[1,arr[1]]),"&deg;)"])   else return ""};function showmatrix(rows,opts){//alert("showMATRIX "+rows+" "+rows.length+"x"+rows[0].length);  var Opts=new Object();    if(arguments.length==2)Opts=getArgs(opts);  if(!Opts.pow)Opts.pow=1;  var a="<table  border=0 cellspacing=0 cellpadding=0 ><tr>"    +"<td valign=middle align=right rowspan="+rows.length+"  class=bkts"+rows.length+">"+oBKT    +"</td><td><table  cellpadding=3 cellspacing=0>";  var ht=40; //(rows.length==2?40:60);  for(var r=0;r<rows.length;r++)   {a=a+"<tr>";    for(var c=0;c<rows[r].length;c++)      a=a+"<td align=center valign=middle class=smaller>"+         (isNb(rows[r][c])?showterms([[rows[r][c],1]])         :typeof(rows[r][c])=="object"?showterms(rows[r][c])         :rows[r][c]         )+"</td>";    a=a+"</tr>"   };  a=a+"</table></td><td valign=middle align=left rowspan="+rows.length+"  class=bkts"+rows.length+">"+cBKT+"</td>"+     (Opts.pow!=1?"<td valign=top>"+showterms([[Opts.pow,1]],"polysmall")+"</td>":"")      +"</tr></table>";  //alert("MAT "+a);  return a};// ---------- OUTPUT FUNCTIONS --------------function spacer(w){return "<img src='empty.gif' width="+w+" alt=' '>"};function middle(exs){var ts=arguments;  if(arguments.length==1)ts=arguments[0];  var s= "<table class=inln><tr>";  for(var i=0;i<ts.length;i++)s+="<td valign=middle>"+ts[i]+"</td>";  return s+"</td></tr></table>"};function inlinemid(ts,OPTS){  if(arguments.length==1)OPTS="";  var s= "<table class=inln><tr>";  for(var i=0;i<ts.length;i++)if(ts[i].length>0)s+="<td valign=middle>"+ts[i]+"</td>";  return s+"</td></tr></table>"};function onelinemid(exs){var ts=arguments;  if(arguments.length==1)ts=arguments[0];  var s= "<table><tr>";  for(var i=0;i<ts.length;i++)     if(ts[i].length>0)s+="<td valign=middle>"+ts[i]+"</td>";  return s+"</td></tr></table>"};function oneline(exs){var ts=arguments;  if(arguments.length==1)ts=arguments[0];  var s= "<table><tr>";  for(var i=0;i<ts.length;i++)s+="<td valign=bottom>"+ts[i]+"</td>";  return s+"</td></tr></table>"}; function spn(x,sty){if(arguments.length==1)sty="poly";   return "<span class='"+sty+"'>"+x.toString().replace(/-/g,minusch)+"</span>"};function showsurdpow(base,pow,sty){  if(arguments.length==2)sty="poly";  if(cmp(pow,"<",0))return Frac(1,showsurdpow(base,neg(pow)),"polysmall");  if(num(pow)==0)return showterms([[1,1]],"poly");  if(isQ(pow))return (sty!=""?"<span class="+sty+">":"")+(den(pow)>2?"<sup>"+den(pow)+"</sup>":"")+"&radic;"             +(num(pow)>1?"(":"")+showsurdpow(base,num(pow),"")+(num(pow)>1?")":"")+(sty==""?"":"</span>");  return (sty!=""?"<span class="+sty+">":"")+base+(num(pow)>1?"<sup>"+num(pow)+"</sup>":"")+(sty==""?"":"</span>");};  function frac(n,d,styl){if(arguments.length==2)styl="";  if(isQ(n)){if(arguments.length==2)styl=d;d=n.bot;n=n.top;};  //if(n==0)return (styl==""?"0":"<span class="+styl+">0</span>");  if(d==0 || !isFinite(n))return (styl==""?"Infinity":"<span class="+styl+">Infinity</span>");  var s=+1;if(isFinite(n) && n<0){n= -n;s=-s};if(isFinite(d) && d<0){d= -d;s=-s};  if(n.toString().indexOf(".")==-1 && d.toString().indexOf(".")==-1)     {var g=gcd(n,d);n=Math.round(n/g);d=Math.round(d/g);       if(d==1)return (styl==""?qnb(s*n):"<span class="+(styl=="polysmall"?"poly":styl)+">"+qnb(s*n)+"</span>")}  else //return FLOAT     return (styl!=""?"<span class="+styl+">":"")+(s<0?minusch:"")+dps(n/d,3)+(styl!=""?"</span>":"");  return "<table cellpadding=0 cellspacing=0 "+(styl==""?"":"class="+styl)+"><tr>"     +(s<0?"<td rowspan=3 align=center>"+minusch+"&nbsp;</td>":"")     +"<td align=center>"+qnb(n)+"</td></tr>"  +"<tr><td height=3><img src='black.gif' height=1 width='100%' alt='---'></td></tr>"  +"<tr><td valign=top align=center>"+qnb(d)+"</td></tr></table>" };  function Frac(n,d,styl,opts){  //RAW fration -- no conversion,sign simp,etc  //alert(n+" / "+d);  if(arguments.length==2)styl="";  if(arguments.length<4)opts="";     OPTS=getArgs(opts);   if(!OPTS.align)OPTS.align="center";  OPTS.minus=opts.indexOf("-")!=-1;  if(n.toString().indexOf("-")!=-1)n=n.toString().replace("-",minusch);  if(d.toString().indexOf("-")!=-1)d=d.toString().replace("-",minusch);  return "<table cellpadding=0 cellspacing=0 "+(OPTS.tabsty?"class="+OPTS.tabsty:"")+"><tr>"   +(OPTS.minus?"<td rowspan=3 class=poly>"+minusch+spacer(3)+" </td>":"")   +"<td align="+OPTS.align+(styl==""?"":" class="+styl)+">"+n+"</td></tr>"  +"<tr><td height=4 valign=middle><img src='black.gif' height=1 width='100%' alt='---'></td></tr>"  +"<tr><td valign=top align="+OPTS.align+(styl==""?"":" class="+styl)+">"+d+"</td></tr></table>"};  function fctrl(n){return n==0||n==1?"1":n==2?"2&times;1":n==3?"3&times;2&times;1":n==4?"4&times;3&times;2&times;1":n+"&times;"+(n-1)+"&times;...&times;1"};function fctrl2(n,r){ return n==r+1?n.toString():n==r+2?n+"&times;"+(n-1):n==r+3?n+"&times;"+(n-1)+"&times;"+(n-2):             n==r+4?n+times+(n-1)+times+(n-2)+times+(n-3) :n+"&times;"+(n-1)+"&times;...&times;"+(r+1)};function negb(n,opts){var opt=getArgs((arguments.length==2?opts:""));   if(opt.no1 && n==1)return "";   return (isNb(n) && n<0?"("+minusch+(-n)+")":n)};function Var(v){return "<i>"+v+"</i>" };function sign(n){return (n<0?"-":"+")};function showsign(n){return (isNb(n)?n<0:n.top<0)?"&ndash;":"+"};function SGN(s){return (s=="-"?" "+minusch:" +") };function shownb(n,opts){// args:  withsign (if present means yes), c=styleclass, dps=NB   var s,args=(arguments.length>1?getArgs(opts):new Object());   if(args.dps){s=dps(n,args.dps)}else{s=n.toString()};   //s=(args.withsign||s<0?showsign(n):"")+s;   if(args.c)s="<span class="+args.c+">"+s+"</span>";   return s};function showcoeff2(c,withsgn){  c=norm(c);  if(arguments.length==1)withsgn=true;       if(num(c)==0)return ""  else if(den(c)==1&&num(c)==1){return (withsgn?" + ":"")}  else if(num(c)==-1&&den(c)==1)return " - "  else {return (num(c)>0?(withsgn? " + ":""):" - ")+abs(c).toString()}};  function showcoeff(c,x,withsgn){  return arguments.length==2? showcoeff3(c,x,"",false) :showcoeff3(c,x,1,withsgn)};  function showcoeff3(c,x,p,withsgn){//alert(c+" "+x);  var res;  if(arguments.length<4){withsgn=false};  if(arguments.length<3||p=="")p=1;  var sgn="+",ABSC=c;  var pow=(p==0||p==1||p==""||p=="sqrt"?"":"<sup>"+p.toString().replace("-",minusch)+"</sup>");  var bktvar= p!=0&&p!=1&&x.toString().indexOf("-")!=-1;  if(bktvar)x="("+x+")";  if(typeof c=="string"){if(c.charAt(0)=="-"){sgn="-";ABSC=c.slice(1)}  else{sgn="+";ABSC=c.toString()}}  else if(typeof c == "number"){sgn=(c<0?"-":"+");ABSC=Math.abs(c).toString()};  if(c==0)return "";  if(ABSC=="1"){if(dbg)document.writeln(c," ",x," ",p," ",withsgn," isFinitex:",isFinite(x)," sgn",sgn," >> ");   res= (withsgn||sgn=="-"?SGN(sgn)+(withsgn?" ":""):"")       +(x==1?ABSC             :isNb(x)&&isFinite(x)             ?" "+(p=="sqrt"?"&radic;":"")+(isVar(x)?Var(x):x)             :(p=="sqrt"?"&radic;":"")+(isVar(x)?Var(x):x))       +pow;if(dbg)document.writeln(res,"<br>")}   else res= (withsgn||sgn=="-"?SGN(sgn)+(withsgn?" ":""):"")+ABSC+                        (x=="1"?"":isFinite(x)?" "+(p=="sqrt"?"&radic;":"")                             +(isVar(x)?Var(x):x):" "                             +(p=="sqrt"?"&radic;":"")+(isVar(x)?Var(x):x))+pow   return res.replace("-",minusch)};function showterms(terms,opts){ //list of [coeff , varstr, power]  //if(terms.length==1&&terms[0][0]==1)document.writeln("showterms "+terms);  if(arguments.length>2)halt("!!!3 args to showterms!!!")  if(arguments.length==1)opts="inspan=true";  if(arguments.length==2&&opts==false){opts="inspan=false"};  //if(arguments.length==2)alert(opts);  var OPTS=getArgs(opts);  if(OPTS.inspan)OPTS.clss='poly';  if(OPTS.polysmall)OPTS.clss='polysmall'; // var s="";for(var p in OPTS)s=s+p+":"+OPTS[p]+"  ";alert(opts+"= "+s);  var s=(OPTS.table?"<table border=1><tr>":""),first=true,res="";  for(var i=0;i<terms.length!=0;i++)   {  s=s+(OPTS.table?"<td>":"")        +(typeof terms[i]=="string"           ? terms[i]            : showcoeff3(terms[i][0],terms[i][1],(terms[i].length>2?terms[i][2]:""),!first)         );     if(typeof terms[i]=="string"){res=res+s;s=""}     else if(i==terms.length-1 || typeof terms[i+1]=="string")        {if(OPTS.dbg)alert("next is "+(i==terms.length-1?"END":terms[i+1])+" and s is "+s);        if(s.replace(/\s/g,"")==""){if(OPTS.dbg)alert("next is "+(i==terms.length-1?"END":terms[i+1])+" and s empty so s:=0");          s="0"};           res=res+s;s=""};     first=(typeof terms[i]=="string"?true:first && terms[i][0]==0);     if(OPTS.dbg)alert(i+": "+terms[i]+" > "+res+" & "+s);      if(OPTS.table)res=res+"</td>"   }   if(OPTS.table)res=res+"</tr></table>";  //if(s=="")s="0";  return (OPTS.clss?"<span class='"+OPTS.clss+"'>":"")+res+(OPTS.clss?"</span>":"")};function defsp(fld,val,defval){ document.f[fld].value=(val==defval?"":val) };var varnames="abcdghkmnpqrstuvwxyz"; //no f - powers overlap with its ascender,no l - looks like 1,no o - like 0, no i,j - complex, no e - confused with E   function newvar(){return newvars(1)};function newvars(nbvars,selectionfrom){   var allvars=(arguments.length==1?varnames:selectionfrom);   var vars=new Array(nbvars),order=permuteBetween(0,allvars.length-1);   for(var i=0;i<nbvars;i++)vars[i]=allvars.charAt(order[i]);   return vars}function newconsecvars(nbvars){   var j=randint(0,varnames.length-nbvars-1);   return varnames.slice(j,j+nbvars);}var alphabet="abcdefghijklmnopqrstuvwxyz";function isVar(ss,opts){if(arguments.length==1)opts="";  if(isFinite(s))return false;  var s=ss.toString().replace(/\s/,"").toLowerCase();  var all=s.replace(/[a-z]/g,"")=="";  if(opts.indexOf("multi")==-1)all=all&&s.length==1;  return  all};  var Women=["Ann","Maria","Hannah","Jessica","Emily","Emma","Sarah","Elizabeth","Lauren","Grace",     "Samantha","Jenny","Amber","Fatima","Leila","Pam","Summer","Shakira","Sabina","Sarah","Selina",     "Sunita","Sofia","Sophie","Maria","Kylie","Chardonnay","Veronica","Willow"],	Men=[ "Abdullah","Adam","Andrew","Anton","Ben","Brandon","Chan","Daniel","Christopher","Dylan",	   "Gabriel","Huan","Jacob","Josef","Michael","John",	   "Kevin","Kal","Jaleel","Malik","Marek","Muhammad","Mustafa","Marco","Mario","Nathan","Pablo","Ping",	   "Omar","Sergei","Vladimir","Ryan","Wei","William"];function gender(P){for(var i=0;i<Men.length;i++)if(Men[i]==P)return "M";return "F"};function pronoun(P){return (gender(P)=="M"?"":"s")+"he"};function price(p){if(p>100)return "&pound;"+dps(p/100,2)  else return p+"p"};  // -------------- TRIG ------------function degtorad(d,opts){return d/180*Math.PI};function radtodeg(r){var d=r/Math.PI*180;  if(Math.abs(d-Math.round(d))<0.0001)d=Math.round(d);  return d};function isNiceAng(r,angunit){ var a ;  if(arguments.length==1)halt("isNiceAng("+r+") needs angunit as 2nd arg");  if(angunit.charAt(0)=="r")a=radtodeg(normAng(r,'r'))  else a=r;  return isNiceAngD(a)}function isNiceAngD(d){d=normAng(d,"d");   for(var i=0;i<niceAng360.length;i++)     if(equalsang(niceAng360[i],d,'d'))return {isNice:true, niceDeg:niceAng360[i]};  return {isNice:false}};   var niceAng90=[0,30,45,60,90],    niceAng360=[-150,-135,-120,-90,-60,-45,-30,0,30,45,60,90,120,135,150,180],    niceAngAxis=[-90,0,90,180];    niceAngnotAxis=[-150,-135,-120,-60,-45,-30,30,45,60,120,135,150];function randSimpTrigAngDeg(non0){// return -180 to +180  if(arguments.length==0)non0="";  return randelt((non0==""?niceAng360:non0=="axis"?niceAngAxis:niceAngnotAxis))};function normAng(a,units){  if(units.charAt(0).toLowerCase()=="d")  {while(a>180)a=a-360;while(a<=-180)a=a+360; /* a in -179..180 */   return a}else if(units.charAt(0).toLowerCase()=="r")  {while(a>Math.PI)a=a-Math.PI;   while(a<=-Math.PI)a=a+Math.PI;  /* in range (-Pi,Pi] now */   return a}else halt("!!! normAng arg 2 missing (which units)")};function normAngD(a){return normAng(a,"d")};function signsinD(a){a=normAngD(a);  return (a==0||a==180?0:Math.sin(degtorad(a))<0?-1:1)};function signcosD(a){return signsinD(90+a)};function equalsang(x,y,unit,err){  if(arguments.length==2)halt("!!! equalsang needs angular unit");  if(arguments.length<4)err=ERR/1000;  // alert(x+"=?="+y+" "+normAngD(x)+" "+normAngD(y));  return equals(normAng(x,unit),normAng(y,unit),err)}; function cosformula(a,b,c,A){return  onelinemid("<b>Cosine Rule</b>: "+     showterms([[1,a,2]," = ",[1,b,2],[1,c,2],[-2,b+c],' cos(',[1,A],")"]) +" &nbsp;or&nbsp; "+      showterms(['cos(',[1,A],") = "]),     Frac(showterms([[1,b,2],[1,c,2],[-1,a,2]]),showterms([[2,b+c]])) )    };     function cosformulaAng(A,a,b,c){  return onelinemid(showterms(['cos(',[1,A],") = "]),     Frac(showterms([(isFinite(b)?[b+"<sup>2</sup>",1]:[1,b,2]),        (isFinite(c)?[c+"<sup>2</sup>",1]:[1,c,2]),         isFinite(a)?[-a+"<sup>2</sup>",1]:[-1,a,2]]),       (isFinite(b)&&isFinite(c)?showterms([["2&times;"+dps(b,3,"s")+          "&times;"+dps(c,3,"s"),1]]):showterms([[2," "+b+c]])))) };function sineRule(b,c,A){return   onelinemid("The <b>Triangle Area formula</b>: "+          showterms([[1,'Area']," = "]),Frac(showterms([[1,b+c],' sin(',[1,A],')']),          "<span class='poly'>2</span>"))  };                  function showsinD(ang,R,v){  // R sin (ang) algebraically;  v (opt) is imag       if(arguments.length<2)R=1;       if(arguments.length<3)v="";  if(dbg)alert("sinr of "+ang+" r="+R+" v="+v);       if(ang== 0)return showNB(0)  else if(ang==30)return (v==""?showNB(div(R,2)):showPOLY(new POLY([0,div(R,2)]),v,"rev") )  else if(ang==45){return showPOLY(new POLY([0,div(R,2)]),"&radic;2"+v,"rev")}  else if(ang==60)return showPOLY(new POLY([0,div(R,2)]),"&radic;3"+v,"rev")  else if(ang==90)return showPOLY(new POLY([0,R]),v,"rev")  else if(ang>90 && ang<=180)  return showsinD(180-ang,R,v)  else if(ang>180 && ang <=270)return showsinD(ang-180,neg(R),v)  else if(ang>270 && ang<360)  return showsinD(360-ang,neg(R),v)  else if(ang>=360)            return showsinD(ang-360,R,v)  else if(ang<0)               return showsinD(360+ang,R,v)};function showcosD(ang,R,v){if(arguments.length==1)R=1;if(arguments.length<3)v="";    return showsinD(90+ang,R,v)};function angQuad(a,u){   var A=(u.charAt(0)=="d"?a:radtodeg(a));   A=normAngD(A);   return (A>0?(A<=90?1:2):(A>=-90?4:3))};//document.writeln("<table border=1><tr><th>a</th><th>sin(a)</th><th>cos(a)</th></tr>");//for(var s=-1;s<=1;s=s+2)//  for(var q=0;q<=3;q++)//    for(var i=0;i<4;i++)//      {var a=s*(q*90+[0,30,45,60][i]);//       document.writeln("<tr><td>",a,"</td><td>",sinr(a),"</td><td>",cosr(a),"</td></tr>");//      };//document.writeln("</table>");function COMPLmod(str){return "<span class=larger>|</span>"+str+"<span class=larger>|</span>"};// --------------------DY/DX ----------------------function dydx(y,x,ord){if(arguments.length==2)ord=1;  return Frac(spn("d"+(ord>1?"<sup>"+ord+"</sup>":"")+Var(y)),spn("d"+Var(x)+(ord>1?"<sup>"+ord+"</sup>":"")),"","align=left")};// ------------------  INPUT and CHECKING ANSWERS --------------function evalstr(fld)  {try{var i=eval(fld.replace("sqrt","Math.sqrt").replace(/infinity/,"Infinity")                .replace(/pi/ig,"Math.PI").replace("E","Math.E"))  }catch(e){}   return i};function checkinput(fld,nm,opts){  // always eval input   var i;   var opts=arguments.length<3?new Object():getArgs(opts);   if(!opts.emptyval)opts.emptyval=""; //Empty always allowed (when clicking on (?) button; use 'emptyval=NaN' otherwise    //alert(nm+" emptyval="+opts.emptyval);   fld=fld.replace(/\s/g,"");   if(fld=="-"){i=-1}   else {var xtra=fld.replace(/sqrt/g,"").replace(/[Ii]nfinity/g,"").replace(/pi/gi,"").replace(/[0-9eE\.\-\*\/+\(\)\s]/g,"")          if(xtra!="" )              halt(nm+": Only numbers, fractions, E, Pi, sqrt, Infinity and -Infinity are allowed in input boxes\nFound "+xtra)              // don't allow trig fns etc          else try{i=evalstr(fld) }               catch(evt){alert("I do not understand your input to "+nm+"\nPlease change it");return NaN}       };     if(isNaN(i))     {//alert(nm+" is NaN");        if(fld=="") i=opts.emptyval // empty fields always allowed as input ELSE use:-       //else if(isemptyinput(fld))halt("The "+nm+" input box must have a value typed in.")      else halt("No number found for "+nm)     };   return i }; function isemptyinput(str){return str.replace(/\s/,'')==''};function equals(x,y,err){   if(arguments.length==2)err=ERR;  //i.e. 3dps accuracy expected   if(!isFinite(x)&&!isFinite(y)&&x.toString()!=""&&x.toString()==y.toString())return true; //allow +/-Infinity   try{x=isQ(x)?x.val:eval(x);y=isQ(y)?y.val:eval(y)}catch(e){alert(x+" ?=? "+y+" "+e)};   return Math.abs(x-y)<=err};function selectedVal(fld){return fld[fld.selectedIndex].value};function markme(isRight,showans){//TCimg=name of tickcross image  if(document.f.tickcrossBTN.value==qmarkBTXT)     {if(isRight()){document.f.tickcrossBTN.value=tickBTXT;document.tickcrossIMG.src='tick.gif'}      else{document.f.tickcrossBTN.value=crossBTXT;document.tickcrossIMG.src='cross.gif'}     }   else if(document.f.tickcrossBTN.value==crossBTXT)      {showans();document.f.tickcrossBTN.value=tickBTXT;document.tickcrossIMG.src='tick.gif'}   else if(document.f.tickcrossBTN.value==tickBTXT)      {document.f.tickcrossBTN.value="";hideSolution('tickcrossAREA'); // document.tickcrossIMG.src='empty.gif';       showSolution()      }}      ;// function markme(isRight,showans){//TCimg=name of tickcross image//   if(endswith(document.tickcross.src,"qmarkbtn.gif"))//      {if(isRight()){document.tickcross.src="tickbtn.gif"}//       else{document.tickcross.src="crossbtn.gif"}//      }//    else if(endswith(document.tickcross.src,"crossbtn.gif"))//       {showans();document.tickcross.src="tickbtn.gif"}//    else if(endswith(document.tickcross.src,"tickbtn.gif"))//       {showSolution()}// }      ;/* div or span has name (default "Soln") passed as string here; its class icanhide; initially hidden*//* include:  tryagainalso=function(){hideSolution('ANS2area')}; */function hideSolution(nm) { if(arguments.length==0)nm="Soln";        if (document.getElementById) {document.getElementById(nm).style.visibility = "hidden";}   else if (document.all) {document.all[nm].style.visibility = "hidden";}   else if (document.layers) {document[nm].visibility = "hide";}   else {var w=eval(nm).style;w.visibility="hidden"};};function showSolution(nm) {if(arguments.length==0)nm="Soln";	     if (document.getElementById) {document.getElementById(nm).style.visibility = "visible"; }     else if (document.all) {document.all[nm].style.visibility = "visible"; } 	else if (document.layers) {document[nm].visibility = "show"; } 	else {var w=eval(nm).style;w.visibility="visible"};};function selectNbSolns(SELnm,HIDEnm){ return "<select name='"+SELnm+"'><option selected value=''>Is this the only answer?...</option>"+  "<option value='1' onClick='hideSolution(\""+HIDEnm+"\")'>There is only one solution</option>"+  "<option value='2' onClick='showSolution(\""+HIDEnm+"\")'>There is a second solution:</option></select>"};function help(){ open('help.html','help','height=450,width=800,resizable,scrollbars').focus(); };var helpbtntxt="<input type=button class=BTN value='Help' name='helpBTN' onClick='help();this.blur()' "+BTNEvents()+">";function helpbtn(){  return helpbtntxt};  var calcbtntxt= "<input type=button class=BTN value='Calculator' name='CalcBTN' onClick='gotocalc();this.blur()'"+ BTNEvents()+">"; //"<a href='javascript:gotocalc();'><img src='calc.gif' border=0 width=70 height=20 title='Shows the pop-up Calculator' name='calcicon' alt='calc'></a>";function calcbtn(){document.writeln(calcbtntxt)};var calcwin;function gotocalc(){   if(!calcwin || calcwin.closed)calcwin=window.open('calc.html','calc_win','menubar=no,status=no,toolbar=no,height=500,width=650,resizable');   calcwin.focus()};function newqubtn(d){ if(arguments.length>0){d=""}else{d="onClick='gotoURL(args.fileQuURL);this.blur()' "}; return "<input type=button class=BTN value='New Question'  name='NewQBTN' " +d+BTNEvents()+">" };   function cleartick(){document.f.tickcrossBTN.value=qmarkBTXT;document.tickcrossIMG.src='empty.gif'};function tryagain(){document.f.reset();cleartick();showSolution('tickcrossAREA');hideSolution();tryagainalso()};var tryagainalso=function(){};   function qtcbtntxt(nm){ //used in help.html only     return "<input type=button class=BTN name='qBTN' "+BTNEvents()+" value='"+nm+"'>"};function qmark(c){if(arguments.length==0)c="";document.writeln(     "<p clear='all'>"    ,"<img src='empty.gif' name='tickcrossIMG' width=27 height=22 alt='tickcross'  >"    ,"<span id='tickcrossAREA'><input type=button align=middle class=BTN name='tickcrossBTN' value='"       ,qmarkBTXT,"' onClick='markme(isRight,showAns);this.blur()' ",BTNEvents(),"></span>"    ,"<div class=btnbar>"    ,"<span style='float:left'>"    ,(c==""?"":calcbtntxt)    ,"<input type=reset class=BTN name='tryagainBTN' "       ,BTNEvents()," value='Let me try again' onClick='tryagain();this.blur()'> "    ,"</span>"    ,"<span style='float:right'>"       ,newqubtn(),helpbtntxt    ,"</span><br clear=all>"    ,"</div>"    )};var qmarkBTXT="    Am I right?     ",      tickBTXT= "Show Worked Solution",     crossBTXT="    Show answer     ",    solnBTXT=""    ;var oldBCol,oldCol,oldCName;function mdown(t){t.className="BTNDown"};function mout(t){t.className=oldCName;t.blur();};function mup(t){t.className="BTNOver";t.blur()};function mover(t){oldCName=t.className;t.className="BTNOver"};function BTNEvents(){return "onMousedown='mdown(this)' onMouseover='mover(this)' onMouseout='mout(this)' onMouseup='mup(this)'"};function footer(d){address(d)};var emailTXT= (location.toString().indexOf("ronknott")==-1?"<img src='sig.gif' width=185 height=16 alt='tom . button [AT] mei . org . uk'>"   :"<img src='rdksig.gif' width=141 height=13 alt='enquiry [AT] ronknott . com'>");function email(){document.writeln(emailTXT)};function address(date,opts){  if(arguments.length<2)opts="";  // if(arguments.length==0||date=="")date=document.lastModified.toString();	document.writeln("<br clear=all><hr size=1 class=hr>");   if(links[args.filename]){document.writeln("<div class=links align=center>");                  for(var i=0;i<links[args.filename].length;i++)document.writeln(links[args.filename][i],(i<links[args.filename].length-1?" | ":""));                   document.writeln("</div><hr size=1 class=hr>");                 };	document.writeln("<address><table width='100%' class=smaller><tr><td style='text-align:left;' align=left><a target='_blank' href='copyright.html'>&copy;</a>",(opts.indexOf("SG")==-1?" MEI Produced by ":""),"Dr Ron Knott, ",date, "<br>",emailTXT," </td>",(opts.indexOf("noref")!=-1?"": "<td align=right valign=top>Test reference: <a href='"+args.fileQuRefURL+"'>"+args.fileQuRefURL+"</a></td>"), "</tr></table></address>");};function header(){  document.writeln('<a href="',args.fileQuURL,'"><h1>',         document.title,'</h1></a>') }; 