
var SYS;
DIR="file:///C:/temp/"; //for images etc wd go with test text (FTEXT)
//PROG="";  // ../sys/";  // for lplite.js and its images

function load() {
  t=navigator.userAgent;
  if(t.indexOf('Mac')>-1) {
    if(t.indexOf('Safari')<0) alert("On a MAC with MSIE, click 'Refresh' or press APPLE+R to show the page correctly. If anyone has an idea how to avoid this need, please contact cusplap@ucl.ac.uk!\n\r"+"OS="+t); }
//alert("NB this tool is under development. Recent errors affecting MCQs are cured, but there is an error with EMQs at present: Answers (e.g. A(4);) need to be entered by hand. Other errors, please email cusplap@ucl.ac.uk.");
  if(SYS) ; else SYS="../sys/";  // for lplite.js and its images
  zblank(true); showfile(); options(); } 

var NEW=0, STEXT="Section text", QTEXT="2+2?", FTEXT="", TEXT=TEXT2="", STATUS=0, TITLE="-", EMAIL="-";
var IMG='', SECTIMG='', QUIMG='', RANDSEQ=false, RANDSEL=1, REPEATS=0, SOPTS=QOPTS=0, SMCN,QMCN,MCQN,MRQN ;
var BUT= "<input type=button value='";
var FOCUS, SMCQ, QMCQ, TMPWIN; 
var ZDEF=new Array(),ZCODE=new Array(),ZS=new Array(),Z=new Array(), SMCQTXT=new Array();

function zblank(all) {for(i=0;i<10;++i) {if(all) ZS[i]=false; if(!ZS[i]) ZDEF[i]=Z[i]=ZCODE[i]='';} }

function Tag(name,code,type) { this.name=name; this.on='<'+code+'>'; 
  if(type==0) this.off='</'+code+'>'; else this.off=''; } 
TAGS=new Array(); TAGS[0]=new Tag('Bold','b',0); TAGS[1]=new Tag('Ital','i',0); 
TAGS[2]=new Tag('Uline','u',0); TAGS[3]=new Tag('Super','sup',0); TAGS[4]=new Tag('Sub','sub',0); 
TAGS[5]=new Tag('NewLine','br',1);
function CHK(i,box) {
  t="<input type='checkbox' name=tag"+i+" onclick='parent.insert("+i+","+box+",this.checked);"
 if(TAGS[i].off=='') t+=" this.checked=false;"; t+="'>";
  t+=parent.TAGS[i].name+ ' '; return t; }
function SYM() {return "<input type='checkbox' name=sym onclick='this.checked=false; parent.getsym();'>Symbol ";}

function TXT1BOX(rows,txt) {return "<textarea name=txt1 rows="+rows+" cols=70 onfocus='parent.FOCUS=\"txt1\";' >"+txt+"</textarea><br>";}
function TXT2BOX(rows,txt) {return "<textarea name=txt2 rows="+rows+" cols=70 onfocus='parent.FOCUS=\"txt2\";' >"+txt+"</textarea><br>";}
function REPSBOX() {return "<input type='text' name='reps' value=" + REPEATS +" size=3>";}
function RSELBOX() {return "<input type='text' name='rsel' value=" + RANDSEL +" size=3>";}
function ENTER(text, type,val) {return BUT +text + "' name='"+type+"' onclick='parent.addtxt(\"\","+val+"); return false'/>";}
function IMGBOX(txt) {return "<input type='text' name='img' size=30 value='" +txt+ "'/>";}
function LINEBOX(txt,n) {return "<input type='text' name='tline' size="+n+" value='"+txt+"' onfocus='parent.FOCUS=\"tline\";'/>";}

//function ENTERLINE(text,type,val) {return BUT+text+"' onclick='parent.addtxt(\""+type+ "\",tline.value); return false'/>";}

function insert(i,box,chk) { 
  p=parent.wsetup.document.oform; 
//alert(box+"|"+FOCUS);
  if(box==-1) p=p.elements[FOCUS]; else {p=(box==2)?p.txt2: (box==0)?p.tline:p.txt1;}
  p.value += (chk)?TAGS[i].on:TAGS[i].off; p.focus(); }  

function ropt(text , val ) { //radio opt: description, value, (checked, name[def=opts])
  var sel="", n="opts"; if(arguments[2]) sel=" CHECKED "; if(arguments.length>3) n=arguments[3];
  return "<input type=radio name=" + n + " value=" + val + sel + "> " + text+" &nbsp;"; } 

function copt(text , val ) { //check opt: description, value, (checked, name[def=opts])
  sel= (arguments[2])? " CHECKED " : ""; 
  t="<input type='checkbox' name='copt"+val+ "' " + sel + "> " + text+" &nbsp;"; return t; } 

function selrand(n1) { //to match fn in lplite.js
  var sep=1,n,n2,n4,r,ex,e=1.E-6,i; //default exclusion range +/- 1e-6
  if(arguments.length<2) return n1; else n2=arguments[1]; 
  if(arguments.length>2) sep=Math.abs(arguments[2]); 
  if(arguments.length>3) ex=arguments[3]; 
  if(arguments.length>4) e=Math.abs(arguments[4]); 
  if(n2<n1) {n=n2; n2=n1; n1=n;} n=n2-n1;  if(n==0) return n1; 
  if(sep!=0) n=1+Math.floor(n/sep);
  for(i=1000;--i;) { 
    r=Math.random(); if(sep==0) r=n1+r*n; else r=n1+sep*Math.floor(n*r);
    if(isNaN(ex)) break; if((r<ex-e)||(r>ex+e)) break; } 
  return r; }

function calcall(ref) { 
  for(i=0;i<10;++i) {
    if((ref<0)||(i==ref)||(ZDEF[i].split("Z["+ref+"]").length>1)) 
     if(((ref==-2)||!ZS[i]) &&(ZDEF[i]!="")) {Z[i]='error'; options(); calcZ(i);} } }

function calcZ(i) { x="Z["+i+"]="; d=ZDEF[i]; 
  d=d.replace(/=/g ,''); d=d.replace(/z\[/g ,'Z['); d=d.replace(/z\[/g ,'Z['); ZDEF[i]=d;
  d=d.split(','); 
  if(d.length>1) x+="selrand("+ ZDEF[i] + "); "; else x+=ZDEF[i]+ "; "; ZCODE[i]=x; 
  x=new Function(x); x(); }

function newZ(i,def) { 
 if(ZS[i]) alert('This is already set for the whole section'); 
 else {ZDEF[i]=def; calcall(i);} options(); }

var T_COMMENTS = "<form name=cform><textarea name=comments rows=2 cols=50></textarea><p><input type=button value='Save Comment' onclick='opener.options(); return false'> <input type=button value='Cancel' onclick='opener.options(); return false'></form>"; 

function getmrq() { //alert("Hi!");
  TMPWIN=self.open("","comwin","width=800,height=200,resizable=yes"); f='parent.document.cform.';
  d=TMPWIN.document; t="<title>MCQ/MRQ</title>With multiple choice options, your question may expect the student to enter :<br><form name=cform>"; 
  t+=ropt("A single response (MCQ) (but NB you may allow more than 1 choice as correct)",1,true) +"<br>";
  t+=ropt("Multiple responses (MRQ,n): <input type=text name=n size=3></input> entries, each with a confidence judgement.",2) +"<br>";
  t+=ropt("An exact selection (MRQ,0) - i.e. marks are only given for the exact set of choices that you will select, made all in one go with a single confidence level. In this case you may select no choices ( - \'none are correct\').",1000)+"<br>"; r="Q(MCQ,\"";
  t+=BUT +"ok' onclick='if(!(("+f+"opts[1].checked)&&("+f+"n.value==\"\"))) {opener.addmrq("+"opts,"+f+"n.value); self.close();} return false;'/>";
  d.write(t+"</form>"); d.close(); TMPWIN.focus(); } //return("Q(MCQ,\""); 

function addmrq(txt,n) {
//alert(txt[0].checked+"|"+txt[1].checked+"|"+txt[2].checked+"|"+n);
  if(txt[0].checked) val=11; else if(txt[2].checked) val=10; else val=10+Number(n); 
  MRQN=val-10; STATUS=2; 
  if(MRQN>SMCN-1) {alert("There are only "+SMCN+" options!"); options(); return;} //MRQ too large 
  x=QOPTS; options(); QOPTS=x; addtxt('',val); }

function options() { 
  var i, d = self.wsetup.document; d.close();
  t="<form name='oform' onsubmit='return false;'> (Status: "+STATUS+") : &nbsp;&nbsp;<b><u>";
  switch(STATUS) {

   case 0: t+="Preliminaries: &nbsp; (Optional) EXERCISE TITLE</b></u>:<p>";   //PRELIMINARIES
    t+="Enter an (optional) TITLE to be shown with the Index :";
    t+=" &nbsp; &nbsp; &nbsp;"+ CHK(1,0)+CHK(2,0)+CHK(3,0)+CHK(4,0)+SYM() +"<br>";
    t+=LINEBOX('',70) +"<br>" + ENTER('None','',0) +" &nbsp;"+ ENTER('Enter','',1);
    FOCUS='tline'; break; 

   case 50: t+="Preliminaries: &nbsp; (Optional) EMAIL</b></u>:<p>";   //PRELIMINARIES
    t+="Enter an (optional) email address for queries/suggestions :  &nbsp;  &nbsp;<br>";
    t+=LINEBOX('',50) +"<br>" + ENTER('None','',0) +" &nbsp;"+ ENTER('Enter','',1);
    FOCUS='tline'; break; 

   case 1: t+="New SECTION</b></u>:<p>"; SECTIMG=''; zblank(true);   //Section
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td><table><tr><td>Section Heading [optional] : &nbsp;&nbsp;&nbsp;";
    t+=CHK(1)+CHK(2)+CHK(3)+CHK(4)+SYM()+"</td></tr>";
    t+="<tr><td>"+TXT1BOX(1,"")+"</td></tr>";
    t+="<tr><td>Text (to appear above Qs): &nbsp;&nbsp;&nbsp;";
    t+=CHK(0,2)+CHK(1,2)+CHK(2,2)+CHK(3,2)+CHK(4,2)+SYM()+"</td></tr>";
    t+="<tr><td>"+ TXT2BOX(5,"") +"</td></tr>";
    t+="<tr><td>Image filename (if any) : &nbsp;&nbsp; "+IMGBOX('') +"</td></tr>";
    t+="</table></td>";
    t+="</table><br>";
    t+="Enter this as : &nbsp;" + ENTER('An information Section (no questions)','S',1) + "&nbsp;&nbsp;";
    t+=ENTER('A section with questions to come','S',2); 
    t+="<br><i>Note that Sections without questions are shown in the index of an exercise as 'Information'</i>";
    FOCUS='txt2'; break; 

   case 101: t+="Options for the start of a New Section with Questions</b></u><p>";  SOPTS=0;//Section
    t+="<table bgcolor='white'>";
    t+="<tr><td><b>RESTRICT</b>: &nbsp; Show only a selection of the Qs (1 Q chosen (at random) from every "+RSELBOX();
    t+=" in the sequence within this section)</td></tr>";
    t+="<tr><td><b>RANDOM ORDER</b>: &nbsp; "+copt('',1,false) +" Randomise the order in which questions in this section are presented</td></tr>";
    t+="<tr><td><b>REPEAT</b>: &nbsp; Repeat this section over again "+ REPSBOX() +" times unless <i>Next Section</i> is clicked</td></tr>";
    t+="<tr><td><b>VARIABLES</b>: &nbsp; "+copt('',5,false);
    t+=" Set up random parameters (unchanged throughout the section, unless reset) before entering questions</td></tr>";
    t+="<tr><td><b>EMQ</b>: &nbsp; "+copt('',3,false);
    t+=" Create MCQ/MRQ default options to be available for multiple questins in the section";
    t+="<tr><td><b>FINAL EXPLANATION</b>: &nbsp; "+copt('',4,false);
    t+=" Create a <i>general explanation</i> for this section (to be shown after all the Qs)</td></tr>";
//    t+="<tr><td>"+copt('',2,false) +" Strip spaces from replies & answers before matching</td></tr>";
    t+="</table><br>";
    t+=ENTER('Accept these settings','foc',1);
    t+=" &nbsp; &nbsp;<i>NB for most purposes just click to accept the default settings above.</i><p>";
    FOCUS='foc'; break; 

   case 102: t+="Set variable parameters for this whole section:</b></u>:<br>"; //Section
   case 103: if(STATUS==103) t+="Set variable parameters for this question :</b></u>:<br>"; 
    t+="<table><td><table bgcolor='white'>";
    t+="<tr><td><i>Definition:</i></td><td><i>Code:</i></td><td><i>Example:</i></td></tr>";
    for(i=0,NSZ=0;i<10;++i) { t+="<tr><td"; if(ZS[i]) {++NSZ; t+=" bgcolor='white'";} t+=">";   
      t+="Z["+i+"] = <input type='text' name='Zdef"+i+"' value='" +ZDEF[i]+ "' size=30 ";
      t+="onchange='parent.newZ("+i+",this.value); return false;' ></td>";
      t+="<td> <input type='text' name='Zc"+i+"' value='" +ZCODE[i]+ "' size=30 ";
      t+="onchange='alert(\"This is derived from the definition\"); parent.options(); return false;' ></td>";
      t+="<td> e.g. : <input type='text' name='Z"+i+"' value='" +Z[i]+ "' size=10 ";
      t+="onchange='alert(\"This is calculated\"); parent.options(); return false;' ></td></tr>"; }
    t+="</table></td><td>";
    if(NSZ>0) t+=ENTER('Recalculate for this Q','',2) +"<p>" + ENTER('Recalculate all','',3);
    else t+=ENTER('Calculate new examples','',2);
    t+="</td></table>" + ENTER('None','',0) +" &nbsp;";
    if(NSZ>0) t+=ENTER('Add the new definition/s, for this Q','',1); else t+=ENTER('Add the definition/s','',1);
    FOCUS=''; break; 

   case 2: t+="New QUESTION</b></u>:<p>"; QUIMG=''; zblank(false); QOPTS=0; QMCQ=new Array();  //Question 
    t+="<table  border='1' bgcolor='white'>";
    t+="<tr><td>Q Text : &nbsp;&nbsp;&nbsp;"+CHK(0)+CHK(1)+CHK(2)+CHK(3)+CHK(4)+SYM()+"</td></tr>";
    t+="<tr><td>" + TXT1BOX(5,TEXT) +"</td></tr><tr><td>"; TEXT='';
    if(SECTIMG!="") t+="Default image filename: "+SECTIMG +"<br>Optional Different filename for this Q:";
     else t+="Image filename (if any) : &nbsp;&nbsp; "; 
    t+=IMGBOX(TEXT2) +"</td></tr>"; TEXT2='';
//    t+="</table></td>";
//    t+="<td bgcolor='white'>"+copt('',1,false) +" Set random parameters<br>for use in this question</td>";
//    t+=copt('',2,false) +" Strip spaces from a<br>text reply before matching</td>";
    t+="</table>";
    t+=copt('',1,false) +" Set new random parameters  (Z[..]) for use in this question<p>";
    t+="<i>Click to enter this as an appropriate type of question (or 'None' to ignore any entries):</i><br>"
    t+=ENTER('None (new Section)','',0) + "&nbsp;&nbsp;" + ENTER('T/F (True)','',1);
    t+="&nbsp;&nbsp;" + ENTER('T/F (False)','',2)  + "&nbsp;&nbsp;"+ ENTER('Text/Numeric Answer','',3);
//alert("opt 2: SOPTS="+SOPTS+" QOPTS="+QOPTS); 
//      t+=ENTER('MCQ/MRQ (creating new options for this Q)','',4); } else
    t+=" &nbsp;" + ENTER('MCQ/MRQ','',4);
    if(SOPTS&1) t+=" &nbsp;" + ENTER('EMQ','',5) ;
    FOCUS='txt1'; break;

   case 3: t+="Text or numeric question: MODEL ANSWER (to be used as feedback)</b></u> <i>NB answers must be plain text: no SYM/FONT options</i>:<br>";
    t+="<i>The Model Answer will be shown as a literal phrase, e.g. '1 gal or 5 litres'. Add alternative answers to allow specific alternative answers.</i><p>";
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td>Text :<br>" + LINEBOX('',70) +"</td></tr>";
    t+="<tr><td>Special explanation (optional) for a reply matching this answer : &nbsp;&nbsp;&nbsp;";
    t+=CHK(0,2)+CHK(1,2)+CHK(2,2)+CHK(3,2)+CHK(4,2)+SYM()+"</td></tr>";
    t+="<tr><td>"+ TXT2BOX(4,"") +"</td></tr></table><br>";
    t+=ENTER('Enter','Model',1) + "&nbsp;&nbsp;"; 
    FOCUS='tline'; break;

   case 4: t+="Text or numeric question: Alternative Answer </b></u> <i>(NB You may enter any number of these)</i>:<br>";
    t+="<i>Enter numeric answers as e.g. {3.14} or {3.1 3.2}, or with units as e.g. {30} mph or {30} m*, text as e.g. London or Lond* or 'New York'<p>";
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td>Alternative Answer Match :<br>" + LINEBOX('',70) +"</td></tr>";
    t+="<tr><td>Special explanation (optional) for a reply matching this answer : &nbsp;&nbsp;&nbsp;";
    t+=CHK(0,2)+CHK(1,2)+CHK(2,2)+CHK(3,2)+CHK(4,2)+SYM()+"</td></tr>";
    t+="<tr><td>"+ TXT2BOX(4,"") +"</td></tr></table>";
    t+=copt('',1,false) +" Strip spaces from the reply and from this answer text before matching<p>";
    t+="<i>Click 'Incorrect' if you want to explain something about this specific wrong answer:</i><br>"
    t+=ENTER('None','A',0) + "&nbsp;&nbsp;" + ENTER('Correct Answer','A',1) + "&nbsp;&nbsp;";
    t+=ENTER('Incorrect Answer','A',2); 
    FOCUS='tline'; break;

   case 5:  t+="(Optional) Explanation to give the student after answering this question</b></u>:<p>"; EXPIMG='';
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td><table><tr><td>Text : &nbsp;&nbsp;&nbsp;"+CHK(0)+CHK(1)+CHK(2)+CHK(3)+CHK(4)+SYM()+"</td></tr>";
    t+="<tr><td>"+TXT1BOX(4,"")+"</td></tr><tr><td>";
    if(QUIMG!="") t+="Image shown with Q: &nbsp;&nbsp; "+QUIMG +"<br>Optional different Image for Explanation:";
     else t+="Image filename (if any) : &nbsp;&nbsp; "; t+=IMGBOX('') +"</td></tr>";
    t+="</table></td></table><br>";
    t+="<i>Identify whether this explanation should be shown always, or only if a student attempts the Q:</i><br>"
    t+=ENTER('None','E',0) + "&nbsp;&nbsp;" + ENTER('Unconditional','E',1);
    t+="&nbsp;&nbsp;" + ENTER('Conditional on a Reply','C',2);
    FOCUS='txt1'; break;

   case 6:  t+="Optional Conditional Explanation (shown only if a reply is made)</b></u>:<p>"; //after E()
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td><table><tr><td>Text for a Correct Answer : &nbsp;&nbsp;&nbsp;"+CHK(0)+CHK(1)+CHK(2)+CHK(3)+CHK(4)+SYM()+"</td></tr>";
    t+="<tr><td>"+TXT1BOX(4,"")+"</td></tr>";
    t+="<tr><td>Text for an Incorrect Answer (if to be different) : &nbsp;&nbsp;&nbsp;"+CHK(0,2)+CHK(1,2)+CHK(2,2)+CHK(3,2)+CHK(4,2)+SYM()+"</td></tr>";
    t+="<tr><td>" + TXT2BOX(4,"") +"</td></tr><tr><td>";
    if(EXPIMG!="") t+="Image shown with Explanation: &nbsp;&nbsp; "+EXPIMG +"<br>(Optional) Change this to:";
     else t+="Image filename (if any) : &nbsp;&nbsp; "; t+=IMGBOX('') +"</td></tr>";
    t+="</table></td></table><br>" + ENTER('None','C',0) + "&nbsp;&nbsp;" + ENTER('Enter','C',1) + " &nbsp;&nbsp;"; 
    FOCUS='txt1'; break;

   case 7:  t+="Conditional Explanation (shown only if a reply is entered)</b></u>:<p>"; //no prior E()
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td><table><tr><td>Text for a Correct Answer : &nbsp;&nbsp;&nbsp;" +CHK(0)+CHK(1)+CHK(2)+CHK(3)+CHK(4)+SYM()+"</td></tr>";
    t+="<tr><td>"+TXT1BOX(4,TEXT)+"</td></tr>"; TEXT='';
    t+="<tr><td>Text for an Incorrect Answer (if to be different) : &nbsp;&nbsp;&nbsp; "+CHK(0,2)+CHK(1,2)+CHK(2,2)+CHK(3,2)+CHK(4,2)+SYM() +"</td></tr>";
    t+="<tr><td>" + TXT2BOX(4,"") +"</td></tr><tr><td>";
    if(EXPIMG!="") t+="Image shown with Explanation: &nbsp;&nbsp; "+EXPIMG +"<br>(Optional) Change this to:";
     else t+="Image filename (if any) : &nbsp;&nbsp; "; t+=IMGBOX('') +"</td></tr>";
    t+="</table></td></table><br>";
    t+=ENTER('None','C',0) + "&nbsp;&nbsp;" + ENTER('Enter','C',1) + " &nbsp;&nbsp;"; 
    FOCUS='txt1'; break;

   case 8:  t+="Extra (unconditional) Explanation Text</b></u>:<p>";
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td><table><tr><td>Extra text (shown below a conditional explanation) : &nbsp;&nbsp;&nbsp;"+CHK(0)+CHK(1)+CHK(2)+CHK(3)+CHK(4)+SYM()+"</td></tr>";
    t+="<tr><td>"+TXT1BOX(4,"")+"</td></tr>";
    t+="</table></td></table><br>" + ENTER('None','E',0) + "&nbsp;&nbsp;" + ENTER('Enter','',1) + " &nbsp;&nbsp;"; 
    FOCUS='txt1'; break;

   case 9:  t+="Section\'s General Explanation (to be shown after all the Qs)</b></u>:<p>";
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td><table><tr><td>Text : &nbsp;&nbsp;&nbsp;"+CHK(0)+CHK(1)+CHK(2)+CHK(3)+CHK(4)+SYM()+"</td></tr>";
    t+="<tr><td>"+TXT1BOX(4,"")+"</td></tr>";
    t+="<tr><td>Image filename (if any) : &nbsp;&nbsp; "+IMGBOX('') +"</td></tr>";
    t+="</table></td></table><br>" + ENTER('None','',0) + "&nbsp;&nbsp;" + ENTER('Enter','',1); 
    FOCUS='txt1'; break;

   case 10: t+="EMQ STYLE: Set MCQ/MRQ Options to be available for the whole Section</b></u> &nbsp; &nbsp;";
    t+=ENTER('None','',0) + "&nbsp;&nbsp;" + ENTER('Enter','',1) + "<p>";
    t+=CHK(0,-1)+CHK(1,-1)+CHK(2,-1)+CHK(3,-1)+CHK(4,-1)+SYM()+CHK(5,-1) +"<br>";
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td></td><td><i>Option</i></td><td><i>Optional explanatory comment whenever selected</i></td>";
    for(i=1;i<25;++i) { t+="<tr><td> "+i+" </td>"
      t+="<td><input type=text name=tln"+i+" value='' size=60 onfocus='parent.FOCUS="+(7+i*2)+";'></td>";
      t+="<td><input type=text name=tln"+i+" value='' size=60 onfocus='parent.FOCUS="+(8+i*2)+";'></td></tr>"; }
    t+="</table>"; 
    FOCUS=9; break;

   case 11: t+="MCQ/MRQ Options, for this Question</b></u>:<br>";
    t+=ENTER('None','',0) + "&nbsp;&nbsp;" + ENTER('Enter','',1) + "<p>";
    t+=CHK(0,-1)+CHK(1,-1)+CHK(2,-1)+CHK(3,-1)+CHK(4,-1)+SYM()+CHK(5,-1) +"<br>";
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td></td><td><i>Option</i></td><td><i>Optional explanatory comment whenever selected</i></td>";
    for(i=1;i<25;++i) {
      t+="<tr><td> "+i+" </td>";
      t+="<td><input type=text name=tln"+i+" value='' size=60 onfocus='parent.FOCUS="+(7+i*2)+";'></td>";
      t+="<td><input type=text name=tln"+i+" value='' size=60 onfocus='parent.FOCUS="+(8+i*2)+";'></td></tr>"; }
//      t+="<td><input type=text name=tln"+i+" value='' size=70 onfocus='parent.FOCUS="+(8+i)+";'></td></tr>"; }
    t+="</table>"; 
    FOCUS=8; break;

   case 12: t="<form name='oform' onsubmit='return false;'>";
    t+="<b><u>MCQ/MRQ Answer(s) [+ optional explanations]</b></u> &nbsp; ";
    t+=CHK(0,-1)+CHK(1,-1)+CHK(2,-1)+CHK(3,-1)+CHK(4,-1)+SYM()+CHK(5,-1); // + ENTER('Enter','',1);
    if(QMCQ && (QMCQ.length>0)) arr=QMCQ; else arr=SMCQ;
    t+="<br><table border=1>";
    t+="<tr><td></td><td width=500><i>Option</i></td><td>+</td><td>-</td><td><i>Comment to give as feedback (optional)</td></tr>";
    for(i=0;i<arr.length;++i) {
      t+="<tr><td>"+(i+1)+" : &nbsp; </td><td>"+arr[i]+"</td>";
      t+="<td bgcolor='white'><input type='checkbox' name='chk"+i+"'></td>";
      t+="<td bgcolor='white'><input type='checkbox' name='chk"+i+"'></td>";
      t+="<td> <input type=text size=50 onfocus='parent.FOCUS="+(9+i*3)+";'></td></tr>"; }
    t+="</table><br>" + ENTER('Enter','',1);
    FOCUS=9; break;

   case 13: t+="MCQ/MRQ Additional Answer</b></u>:<p>";
    t+="<table border='1' bgcolor='white'>";
    t+="<tr><td><table><tr><td>Sequence Number : &nbsp;&nbsp;&nbsp;<br>";
    t+=LINEBOX('',70) +"</td></tr>";
    t+="<tr><td>Special explanation (optional) when this option is selected : &nbsp;&nbsp;&nbsp;"+CHK(0,2)+CHK(1,2)+CHK(2,2)+CHK(3,2)+CHK(4,2)+SYM()+"</td></tr>";
    t+="<tr><td>"+ TXT2BOX(4,"") +"</td></tr>";
    t+="</table></td></table><br>";
    t+=ENTER('No more answers','A',0) + "&nbsp;&nbsp;" + ENTER('Correct Answer','A',1) + "&nbsp;&nbsp;";
    t+=ENTER('Incorrect Answer','A',2); 
    FOCUS='tline'; break;

   default: t+="Invalid STATUS<br>"+ ENTER('OK','E',0) ; d.write(t+"</form>"); d.close(); return; }

  d.write(t+"</form>"); d.close(); d=d.oform; if(FOCUS=='') return;
  if(FOCUS=='tline') d=d.tline; if(FOCUS=='txt1') d=d.txt1; if(FOCUS=='txt2') d=d.txt2; if(FOCUS=='foc') d=d.foc; 
//alert("FOCUS="+FOCUS+"| d="+d);
  if(!isNaN(FOCUS)) d=d.elements[FOCUS];
  d.focus();  }

function addtxt(type,val) { comment=""; 
  if(val==0) entry=-1; else {entry=chkenter(); if(entry<0) return;} 
  post="\");"; pre=''; imgtxt=""; f=self.wsetup.document.oform;  
  if(f.img) {IMG=f.img.value; if(IMG!="") imgtxt="\n" + "IMG(\"" + IMG + "\");";}
  switch(STATUS) {
   case 0: // Title
    if(entry<0) {STATUS=50; options(); return;} val=f.tline.value; 
    val=chktags(val); if(val=='badtag') return; 
    STATUS=50; if(val!='') pre="TITLE(\""; break;
   case 50: // Email
    STATUS=1; if(entry<0) {options(); return;} val=f.tline.value; if(val!='') pre="EMAIL(\""; break;
   case 1: pre="\nS(\""; SECTIMG=IMG; SMCQ=new Array(); 
    if(val==2) STATUS=101; if(f.txt2.value=="") f.txt2.value=" "; break;
//    if(entry==4) STATUS=9; if(entry==3) {STATUS=10;} 
   case 101: pre=''; STATUS=2; val=''; 
    if(f.copt1.checked) val+='RANDSEQ=1; ';
//    if(f.copt2.checked) val+='STRIP=1; ';
    if(f.rsel.value>1) val+='RANDSEL='+f.rsel.value +'; '; 
    if(f.reps.value>0) val+='REPEATS='+f.reps.value +'; ';
    if(f.copt4.checked) {STATUS=9; SOPTS|=2;} //expl
    if(f.copt3.checked) {STATUS=10; SOPTS|=1;} //mcqs 
    if(f.copt5.checked) {STATUS=102; SOPTS|=4;} //set randoms 
    if(val!='') FTEXT+="\nRET(\""+val +"\");"; if(comment!="") FTEXT+=" //"+comment; pre=""; break; 
   case 102:  //set for section
    if(val==2) calcall(-1); 
    else { if(SOPTS&1) STATUS=10; else if(SOPTS&2) STATUS=9; else STATUS=2; 
      if(val==1) { t=''; for(i=0;i<10;++i) if(ZCODE[i]!='') {t+=ZCODE[i]; ZS[i]=true;} 
        if(t!='') FTEXT+="\nRET(\"" +t+ "\");"; showfile(); } }
    options(); return;
   case 103:  //set for Q  
    if(val==2) calcall(-1); else if(val==3) calcall(-2);
    else { if(QOPTS&1) STATUS=3; else if(QOPTS&2) STATUS=11; else if(QOPTS&4) STATUS=12; else STATUS=5;
      if(val==1) {t=''; for(i=0;i<10;++i) if(!ZS[i] && (ZCODE[i]!='')) t+=ZCODE[i]; 
        if(t!='') FTEXT+="\nRET(\"" +t+ "\");"; showfile(); } }
    options(); return;

   case 2: //NEW QUESTION
    if(entry<0) {
      if(f.txt1.value!='') {alert('Either enter or delete the question text!'); return;} //'None' with entry
      STATUS=1; options(); return; } 
    if((f.txt1.value=='')&&(f.img.value=='')) {
      alert("A question must have specific text or a specific image!"); return;}
    pre="Q(\""; STATUS=5;
    if(val==1) post="\",T);";
    if(val==2) post="\",F);";
    if(val==3) {STATUS=3; QOPTS|=1;}
    if((val==4)||(val==5)) { TEXT=f.txt1.value; TEXT2=IMG;
      if(val==4) {STATUS=11; QOPTS|=2;} 
      else if(val==5) {STATUS=12; QOPTS|=4;}
      pre=getmrq(); return; }  //  pre="Q(MCQ,\""; return; }  // XXXX
    if(val>9) { pre="Q("; if(val==11) pre+="MCQ,\""; else pre+="MRQ,"+(val-10)+ ",\""; 
//alert(QOPTS);
      if(QOPTS&4) STATUS=12; else STATUS=11; break; }
    if(f.copt1.checked) STATUS=103; //set randoms 
//    if(f.copt2.checked) post+="\nRET(\"STRIP=1;\");";
    if(IMG!="") QUIMG=IMG; else QUIMG=SECTIMG; break;

   case 3: val=f.tline.value; //model Answer
    if(val=='') {alert('No answer text!'); return;} STATUS=4; pre="A(\""; break; 

   case 4: 
    if(entry<0) {
      if(f.tline.value!='') {alert('Either enter or delete the answer text!'); return;} //'None' with entry
      STATUS=5; options(); return; } 
    if(f.tline.value=='') {alert('No answer text!'); return;}
    if(val==1) pre="A(\""; 
    if(val==2) { pre="I(\"";
      if(f.txt2.value=='') {
        alert('Only identify specific incorrect answers if you want to give relevant explanations!'); return; } } 
    if(f.copt1.checked) {post="\",1);"; if(f.txt2.value=='') f.txt2.value=' '; } //STRIP 
    val=f.tline.value; break; // Answer

   case 5: 
    if(entry<0) {STATUS=2; options(); return;} 
    if(IMG!="") EXPIMG=IMG; else EXPIMG=QUIMG;
    if(val==1) {STATUS=6; TEXT=""; pre="E(\"";} 
    else if(val==2) {STATUS=7; TEXT=f.txt1.value; options(); return;} break;
   case 6: STATUS=8; if(entry<0) {STATUS=2; options(); return;} pre="C(\""; break;
   case 7: STATUS=8; if(entry<0) {STATUS=2; options(); return;} pre="C(\""; break;
   case 8: STATUS=2; if(entry<0) {options(); return;} if(f.txt1.value=='') {options(); return;} pre="E(\""; break; 
   case 9: STATUS= 2; if((entry<0)||(f.txt1.value=='')) {options(); return;} pre="ES(\""; break; 

   case 10: if(entry<0) {SOPTS&=1022; if(SOPTS&2) STATUS=9; else STATUS=2; options(); return;}

   case 11: if(entry<0) {STATUS=2; options(); return;} 
    if(STATUS==10) arr=SMCQ; else arr=QMCQ; n=f.elements.length; j=0; pre=''; 
    for(i=9;i<n;i+=2) {
      t=f.elements[i].value; if(t=='') continue; row=Math.floor((i-7)/2);
      t=chktags(t); if(t=='badtag') {alert("Bad tag at "+row+"a"); return;}  
      arr[j]=t; ++j; pre+="\nMC(\""+t+"\"";
      t=f.elements[i+1].value; if(t!='') { t=chktags(t); 
        if(t=='badtag') {alert("Bad tag at "+row+"b"); return;} pre+=",\""+t+"\""; } 
      pre+="); \/\/ "+j; } 
    FTEXT+=pre; SMCN=j; pre=''; 
    if(STATUS==10) {if(SOPTS&2) STATUS=9; else STATUS=2;} else STATUS=12; break;
 
  case 12: t=''; n=f.elements.length-1;  //MCQ/MRQ correct answers
    for(j=0,i=7;i<n;i+=3) {
      if(f.elements[i].checked) {
        if(f.elements[i+1].checked) {alert("Both correct and incorrect checked at"+((i-4)/3)); return;}
        ++j; t+="\nA("+((i-4)/3) + ",\""+ f.elements[i+2].value + "\");"; } }
    if(j<MRQN) {alert("Check at least "+MRQN+" correct answer/s"); return;} 
    for(i=7;i<n;i+=3) {
      if(f.elements[i+1].checked) {
        if(f.elements[i+2].value=='') {
          alert("Only check incorrect answers if a comment is to be given: Option "+((i-4)/3)); return; }
        t+="\nI("+((i-4)/3) + ",\""+ f.elements[i+2].value + "\");"; } }
    for(i=7;i<n;i+=3) {
     if((!f.elements[i].checked)&&(!f.elements[i+1].checked)&&(!f.elements[i+2].value=='')) {
       alert("Delete comment not associated with an identified correct or incorrect answer at"+((i-4)/3)); return;} }
    FTEXT+=t; pre=''; STATUS=5; break;  

   case 13: // MCQ/MRQ Additional Answer
    if(entry<0) {STATUS=5; options(); return;} 
    n=f.tline.value; if(isNaN(n)) {alert('Must have a number as the answer!'); return;}
    if(val==2) pre="I("; else pre="A("; t=f.txt2.value; n=n.replace(/ /g,""); 
    if((t=='')&&(val==2))  {alert('Identifying a specific incorrect answer is pointless unless you want to give an explanation tailored to the answer!'); return;}
    FTEXT+="\n"+pre+n; if(t!='') {t=chktags(t); t=cleantxt(t); FTEXT+=",\""+t+"\"";} //badtag?
    FTEXT+=");"; if(comment!="") FTEXT+=" //"+comment; pre=""; break; 
   default: STATUS=1; options(); return; }

  if(pre!="") { 
    if(f.txt1) {t=f.txt1.value; t=chktags(t); if(t=='badtag') return; else f.txt1.value=t;}
    if(f.txt2 && f.txt2.value) {t=f.txt2.value; t=chktags(t); if(t=='badtag') return; else f.txt2.value=t;}
//alert(f.txt1.value);
//alert(cleantxt(f.txt1.value));
    if(f.txt1) val=f.txt1.value; FTEXT+="\n" + pre + cleantxt(val); 
    if(f.txt2 && f.txt2.value) FTEXT +="\",\"" + cleantxt(f.txt2.value);
    FTEXT+=post;  if(comment!="") FTEXT+=" //"+comment; FTEXT+=imgtxt; }
  showfile(); options(); }

function chkenter() {
  o=self.wsetup.document.oform.opts; value=0;
  if(o) value=getmultvalue(o);  
  if(value<0) alert("Select one of the entry options"); return value; }

function getmultvalue(barray) { var i; 
  var s; for(i=0 ; i<barray.length ; ++i) {
    if(barray[i].checked) return barray[i].value; s=barray[i].value;
    if(s!=null) {if(s.search(/^[tyvoj]/i)==0) return 1; if(s.search(/^[fn]/i)==0) return 0;} }   return -1; }

function chkdir(dir) {
  dir=dir.split(" "); dir=dir.join(""); // remove spaces
  dir=dir.split("\\"); dir=dir.join("/"); //replace \ with /;
  j=dir.lastIndexOf('/'); if(j<dir.length-1) dir=dir+'/';
  j=dir.indexOf(':'); if(j==1) dir="file:///"+ dir;
  j=dir.indexOf('www.'); if(j==0) dir="http://"+ dir;
  DIR=dir; 
//  alert(dir);
  return(dir); }

function showfile() {
  d=self.wtext.document; 
  t="<form name=file_form onsubmit='return false;'>";
  t+="<small><b>File Text</b><i> (This is created by entries made above, but you can also edit or delete the text directly, with care).</i>";
  t+=" &nbsp; <b><a target='_blank' href="+SYS+"lplman.htm>Full Manual</a></b>";

  t+="<font color='white'><textarea name=ftext onchange='parent.edited(); return false;' rows=6 cols=90>"; t+=FTEXT+"</textarea></font>";
  t+="<br><b>IMPORTANT</b>: When finished, before testing, and occasionally to avoid losng work, <b>Save the File Text</b> on your computer : <br>Click on ";
  t+="<a href='' onclick='parent.filewin(); return false;'>Show the text in a new window</a> and follow the instruction. Eventually, rename it as a '.js' file for use.";

//<i>Select</i> it (with the mouse or by a <i>Right Click</i> in the box and <i>Select All</i>).<br>"
//  t+="Then <i>Copy</i> and <i>Paste</i> the text into Notepad or a Word Processor, and save it <i>as a .txt file</i> on your own drive."
//  t+="<br><a href='' onclick='parent.filewin(); return false;'>Show the text in a new window</a>";
  t+="<br>You can : <a href='' onclick='parent.testwin(); return false;'>Test the exercise in a new window</a>";
  t+=" &nbsp; and  &nbsp;<a href='' onclick='parent.errwin(); return false;'>Show error console (Netscape only)</a>";
  t+="<br><b>Directory for images etc.: </b><input type='text' name='dir' value=" + DIR +" size=60  onchange='value=parent.chkdir(value); return false;' > <i>(Only relevant during test)</i>";
  t+=" <i>This DIR or URL will be treated like the directory in which the exercise file will eventually be placed. Place ancillary Graphic and HTML files here, referring to them just by filename or relative path.</i></small>";
  t+=" <b><a target='_blank' href=http://www.ucl.ac.uk/lapt/web/comment.php?authoring>Make/Read Comments </a></b>";
  t+="</form>";
  d.write(t); d.close(); d.bgColor='white';
//alert('Hi!');
  parent.wtext.document.file_form.ftext.scrollTop = parent.wtext.document.file_form.ftext.scrollHeight; }

/*
function symhtm(t) {
//  t=t.replace(/& /g , "&amp; ");  
  n=t.length; u="";
  for(i=0;i<n;++i) {c=t.charAt(i); cd=c.charCodeAt(0); if(cd<128) u+=c; else u+="&#"+cd+";";}
  u=u.replace(/\s\s/g , " &nbsp;"); //code for extra space
  return(u); }
*/

function symhtm(t) { 
  t=t.replace(/\s\s/g , " &nbsp;"); //code for extra space
  return(t); }

function chksym(t) { uni=0; n=t.length;
  for(i=0;i<n;++i) if(t.charCodeAt(i)>255) uni=1; return(uni); }

function cleantxt(t) { //turn text to html line
  if(!t||(t=='')) return(''); 
  t=t.replace(/\\\\/g , "TAGZ\\"); t=t.replace(/\\/g , "\\\\"); t=t.replace(/TAGZ\\/g , "\\\\"); // \ -> \\
  t=t.replace(/\\\"/g , "TAGZ\""); t=t.replace(/\"/g , "\\\""); t=t.replace(/TAGZ\"/g , "\\\""); // " -> \" 
  t=t.replace(/\n/g , "<br> ");   //eol -> <br>
  t=t.replace(/\r/g , "");        //del \r
  t=t.replace(/<br> $/,"");   //del terminal eol
  return t; }

function chktags(t) { var i;  if(t=='') return(''); extra=''; 
  for(i=0;i<TAGS.length;++i) {
    if(TAGS[i].off=='') continue; //type 1: only an on tag
    n1=(t.split(TAGS[i].on)).length; n2=(t.split(TAGS[i].off)).length;
    if(n1<n2) {alert('unmatched '+TAGS[i].off); return('badtag');} 
    if(n2>n1+1) {alert('multiple '+TAGS[i].on +' without ' +TAGS[i].off); return('badtag');} 
    if(n1==(n2+1)) extra+=TAGS[i].off; }
  t+=extra;
  for(i=0;i<TAGS.length;++i) { if(TAGS[i].off=='') continue;
    p=TAGS[i].on+TAGS[i].off; p=RegExp(p,"g"); t=t.replace(p,""); } //del <x></x>
//  cleantxt(t);
  return(t); }
 
function edited() {
  v=self.wtext.document.file_form.ftext.value; 
//alert(v.substring(0,2));
  FTEXT=self.wtext.document.file_form.ftext.value.replace(/\u201C/g ,'"'); FTEXT=FTEXT.replace(/\u201D/g ,'"'); //xxx
  self.wtext.document.file_form.ftext.value=FTEXT;  
  self.wsetup.focus(); }

function filewin() {
  FWIN=parent.open("","TEXT", "width=800,height=600,titlebar=1,menubar=1,scrollbars=1,resizable=1"); 
  d=FWIN.document; d.close();
  d.open("text/plain"); //text/plain 
//  d.write("<head><title>AUTHORING TEXT</title>To view and save the text correctly, do: (on a PC) right-click here, then 'View Source' or (on a MAC) click 'View', 'Source'.<br>\n\r Then delete this header, and save the file.<br><br></head>\n\r\n\r");

  if(chksym(FTEXT)) d.write("// **NB includes UNICODE chars. Save this as a TEXT (.txt not .js) file with UNICODE encoding.\r"); 
  else d.write("//Save this as a plain TEXT (.txt not .js) file.\r");
  d.write("// **Then rename it as *.js to use it.\n\r");
  d.write(FTEXT); d.close();
  FWIN.focus();}

function testwin() {
  filewin();
//alert("NB in Internet Explorer for some mysterious reason, you may need to do 'refresh' to get this new window to work'");
  var w=(screen.availWidth-10).toString(), h=(screen.availHeight-30).toString(); 
  TWIN=open("","test","innerWidth="+w+",width="+w+",innerHeight="+h+",height="+h+",left=0,top=0,screenX=0,screenY=0,titlebar=1,menubar=0,scrollbars=1,resizable=1");
  d=TWIN.document;  
  d.write("Please wait!"); d.close(); 
  d.open();
  t= "<html><head><title>TEST</title>\n\r";
  t+="<script type='text/javascript'>var FINI='CLOSE'; SYS='"+SYS+"'; DIR='"+DIR+"'; </"+"script>\n\r";
  t+="<script type='text/javascript' SRC='"+SYS+"lplite.js'></"+"script>\n\r";
  d.write(t);  //NB MSIE can get in a twist if there isn't a pause here. It tries to exec FTEXT before loading lplite.

  alert("NB In case of faults, an AUTHORING TEXT window has also been opened.\n\rIf you forgot to save the text, consider using it now to save the text!");
  t="<script type='text/javascript'>\n\r" +FTEXT+"</"+"script>\n\r";  //in explorer needed to stop executing before lplite
  t+="</head><frameset rows=150,20 onload='load();'>";
  t+="<frame name='display' src=''><frame name='feedback' src='' noresize></frameset></html>";
  d.write(t);
//alert(t);
  d.close(); 
//alert("test");
  TWIN.focus(); }

function errwin() {
  alert("NB in Explorer, errors may be indicated by an alert icon in the bottom L of the window. If this appears, try clicking it to get error diagnostic information");
//  EWIN=parent.open("","","width=800,height=600,resizable=yes"); 
  location='javascript:'; }

function inssym(txt) { p=parent.wsetup.document.oform;
  p=(FOCUS=='tline')? p.tline : (FOCUS=='txt1')? p.txt1 :  (FOCUS=='txt2')? p.txt2 : p.elements[FOCUS];
  p.value+="&"+txt+";"; SYMWIN.close(); this.focus(); p.focus(); }

function instxt(txt) { p=parent.wsetup.document.oform;
  p=(FOCUS=='tline')? p.tline : (FOCUS=='txt1')? p.txt1 :  (FOCUS=='txt2')? p.txt2 : p.elements[FOCUS];
  p.value+=txt; SYMWIN.close(); this.focus(); p.focus(); }

//function r(text , val ) { if(!val) val=text; t="<td> <input type=button title="+val+" value=&" + val;
//  t+="; onclick='opener.inssym(this.title); return false;' > </td>"; return t; }

function r(text , val ) {  if(!val) val=text; 
  t="<td> <input type=button title="+val+" value=&" + val;
  t+="; onclick=\"sform.text.value+=this.value; sform.text.focus(); return false;\" > </td>"; return t; }

function getsym() { 
  SYMWIN=self.open("","symwin","width=1200,height=550,resizable=yes,scrollbars=yes"); 
  var d=SYMWIN.document; t="<title>SYMBOLS</title><form name='sform'>";
  t+="<input type='text' name='text' size=60 value=''> ";
  t+="<input type=button title=insert value=insert  onclick='opener.instxt(sform.text.value); return false;'><p>";
//  t+="<input type='text' name='literal' size=60 value=''><p>";

  t+='<table>'+symset(192,214,24)+symset(224,246,24)+symarr(symacc1,24)+symarr(symacc2,24)+symarr(symsym,24)+'</table>';
  t+='Math <table>'+symarr(symmath,24)+'</table>';
  t+='Greek <table>'+symarr(symgrk,24)+'</table>';
  t+='Cyrillic <table>'+symset(1040,1063,24)+symset(1072,1095,24)+symset(1064,1071,24)+symset(1096,1103,24)+'</table>';
//  t+='<table>'+symset(256,2000,20)+'</table>';
  t+="</form>"; d.write(t); d.close(); SYMWIN.focus(); }

function symset(start,fin,cols) { t='<tr>';
  for(i=0, j=start;;++j) {t+=r('#'+j); if(j==fin) {t+='</tr>'; break;} if((++i)%cols==0) t+='</tr> <tr>';}
  return t; }

function symarr(arr,cols) { fin=arr.length; t='<tr>';
  for(j=0;;) {t+=r(arr[j++]); if(j==fin) {t+='</tr>'; break;} if(j%cols==0) t+='</tr> <tr>';} return t; }

symacc1=new Array('#216', '#217', '#218', '#219', '#220', '#221', '#222', '#159', '#140', '#138', '#142', 'szlig','sigmaf', 'thetasym', 'piv', 'upsih', 'alefsym', 'image', 'real', 'weierp');
symacc2=new Array('#248', '#249', '#250', '#251', '#252', '#253', '#254', '#255', '#156', '#154', '#158', '#161', 'clubs', 'diams', 'hearts', 'spades'); 

symgrk=new Array( 
'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi', 'Omicron', 'Pi', 'Rho',  'Sigma', 'Tau', 
'Upsilon', 'Phi', 'Chi', 'Psi', 'Omega','alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'omicron', 'pi', 'rho',  'sigma', 'tau', 
'upsilon', 'phi', 'chi', 'psi', 'omega');

symmath=new Array('#188', '#189', '#190', '#176', '#186', '#185', '#178', '#179', 'nabla', 'plusmn', 'times', 'divide', 'minus','#151','#175',  'sim', 'prop', 'ne', 'equiv',  
'asymp', 'cong', 'prime', 'Prime', 'radic', 'sdot', 'le', 'ge', 'infin', 'fnof',  
'sum', 'prod', 'int',  'part', 'hellip', 'or', 'and',  
'lowast', 'there4', 'forall', 'exist', 'cup', 'cap', 'sup', 'supe', 'otimes', 'oplus',  
'empty', 'not', 'isin', 'notin', 'sub', 'nsub', 'sube', 'ang', 'perp',  
'hArr', 'rArr', 'lArr', 'uArr', 'dArr', 'harr', 'larr', 'uarr', 'rarr', 
'darr', 'crarr'); 

symsym=new Array('#162', '#163', '#165', 'euro', 'loz', 'reg', 'copy', 'trade', '#170', '#134', '#135', '#164', '#137', '#139', '#187', '#182', '#191', '#166', '#167', '#168', '#149');



