/* ============
   Functions used to modify control, spec, and modules files.
*/


/*  ============ CONTROL PANEL VIEWER FUNCTIONS  */
function goControlA(usenam) {
 var toget ;
  toggleDisplay('doModify',0);
  var toget=getControlXML_1.replace(/\$NAME\$/g,usenam) ;

// now get basic descriptor xml file and modify it
    Get_xmlFile(toget,['controlNode','','1'],'retrieving a control file ','goControlB',usenam,1) ;
    return 1 ;

}


//=========== VIEW CONTROL FILE
// this is called after control file is gotten
function goControlB(usenam,useopen) { 

var innc,nlist,inode,parentn,iii,cnode,goo,toget;
var stuff2,afile,m,i1,i2,foo ;
var aline,doname,amess,tmp1,tmp,tmp0;

enableTextSave=0 ;                     // do  allow saveing of stuff in text box

// got control file
if (useopen==1) {

 updateStatus('Control file retrieved for '+usenam,1);

 foo=controlNode.getElementsByTagName('INCLUDE');

 if (foo.length==0) {
    alert('Error: no <INCLUDE> of control file (perhaps this instrument was not created using the create-an-instrument tool? ');
    return 1;
 }
 updateStatus('Control file: found '+foo.length+' includes (generic, and possibly custom).',1);

 includeFiles=[];
 for (m=0;m<foo.length;m++) {
     afile=getAttributes(foo[m],'file','');
     if (afile=='')  continue ;
     afile=strip(afile).toUpperCase();

     i1=afile.indexOf('CONTROL_GENERIC.XML');
     if (i1>-1) {
        isControl=1 ;
     } else {
       i1=afile.indexOf('CONTROLOE_GENERIC.XML');
       if (i1>-1) {
          isControl=2 ;
       } else {
          includeFiles[includeFiles.length]=afile;        
       }
    }                   // if
 }                     // for
 updateStatus('Control file: found '+includeFiles.length+' custom includes: '+includeFiles,1);

 if (isControl==0) {
    alert('Error:  <INCLUDE> of control file does not point to CONTROL_GENERIC or CONTROLOE_GENERIC  ');
    return 1;
 }
 onInclude=-1;
 goControlB(usenam,2) ;
 return 1;
}


if (useopen==2) {
  if (onInclude>-1) {
     if (includeNodeErr==200) {
        includeFilesContent[onInclude]=includeNodeInc ;
     } else {
        alert('Warning: ('+onInclude+') include file not found on server='+includeFiles[onInclude]);
        includeFilesContent[onInclude]=0 ;
     }
  }
  onInclude++;
  if (onInclude<includeFiles.length) {
    afile=includeFiles[onInclude];
    if (afile.indexOf('/')<0) {
      afile=getParamsXML.replace(/\$NAME\$/g,usenam)+afile ;
    }
    afile=afile.replace(/~/g,'');
    updateStatus('Control file: retrieving include file '+afile,1);

    Get_xmlFile(afile,['includeNodeInc','includeNodeErr','1'],'retrieving a control file include file ','goControlB',usenam,2) ;
    return 1 ;
  } else {
        updateStatus(' Number of include files read= '+includeFiles.length);
  }

}


/*  =======  
 if here, got all include files. Now pull out the important sections:
 In INIT
   <SET>
   <DO> 
   <LOAD> 

 In ATTRIBUTES
     sub _customAttributes

 In DISPLAY
      sub _TaskHeader:     written above the "default" tasks tables. 
      sub _CustomTasksPre:  written below the "Pre-session tasks" table
      sub _CustomTasks1  :  written below the  "Generic" tasks table.
      sub _CustomTasks2  :  written after _CustomTask1

// <SUB>s

// <DO>s

// <FORM>s
====  */


//  pullout <SUB> stuff  (get the _init, etc subs )
subList={};
theSubs=E2_getNodes(controlNode,'sub');
for (var m=0;m<theSubs.length;m++) {
  aname=getAttributes(theSubs[m],'name','');
  aname=strip(aname).toUpperCase();
  if (aname==='') {
        alert('Error: <SUB> without a name: '+m);
        return 1;
  }
  subList[aname]=theSubs[m];
}

aline=[];
stuff2=' ';

aline[1]=' <td><em>There are three pre-defined actions you can &lt;set&gt; .. </em>';

aline[0]='<table><tr><th><a title="click to display the three <SET> components" href="#" onClick="displayDiv(\'showsets\');return false;">&lt;set&gt;</a></th> \n ';
tmp=makeFuncCall('showStuffSub','_INITSET','INIT: initializing variables') ;
aline[1]=' <td><em>There are three pre-defined actions you can &lt;set&gt; .. </em> '+
        ' <div  id="showsets" style="display:none"><ul> '+
        ' <li><input type="button" value="<SET> Initialize varibles"  onClick="'+tmp+'"  /> ';
tmp=makeFuncCall('showStuffSub','_INITDO','INIT: running a DO when the control panel starts');
aline[2]='<li><input type="button" value="<SET> Call a <DO> when control-panel is loaded"  onClick="'+tmp+'"  /> ';
tmp=makeFuncCall('showStuffSub','_INITLOAD','INIT: loading javascript libraries ');
aline[3]='<li><input type="button" value="<SET> LOAD a library"  onClick="'+tmp+'" /> ';
aline[4]='</ul></div></td></tr></table> ';

for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}


 currentTaskDisplay('<div class="displayFiles"> <h4>View the control file, and its components</h4> ' + 
                     '<a  title="Click here ... to view the entire control panel program file " '+
                     ' href="#" onClick="showControlFile(1,0); return false">The control file</a></div> ',stuff2);
 currentTaskDisplay(1);


// 2nd: display attributes
aline=[]; stuff2='';

aline[0]='<table><tr><th><a title="click to display the <ATTRIBUTES> components" href="#" onClick="displayDiv(\'showattributes\');return false;">&lt;attributes&gt;</a></th> \n ';
tmp=makeFuncCall('showStuffAttributes','_CUSTOMATTRIBUTES','ATTRIBUTES for control panel elements');
aline[1]='<td><div id="showattributes" style="display:none"><ul>';
aline[2]='<li><input type="button" value="<ATTRIBUTES> Display "  onClick="'+tmp+'" /></li> ';
aline[3]='</ul></div></td></tr></table> ';

for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}
currentTaskDisplay(2,stuff2);

// 3rd: <PANEL> components
aline=[]; stuff2='';
stuff2='<table rules="rows"><tr><th><a href="#" onClick="displayDiv(\'showdisplays\');return false;" title="click to display the five pre-defined components of the  <PANEL> "> &lt;PANEL&gt;</a></th> \n  ';
stuff2=stuff2+'<td><em>The control-panel contains 5 pre-defined areas (on the browser screen) ' +
              ' that are used to display content ... </em>  ' +
              ' <div id="showdisplays" style="display:none;margin-left:10px;"> '+
             '  <table>';

tmp=makeFuncCall('showStuffDisplay',1,'_TASKHEADER','DISPLAY: Task Header');
aline[1]='<input type="button" value="<PANEL> : Task Header (written above the default tasks tables)" onClick="'+tmp+'" /> ';

tmp=makeFuncCall('showStuffDisplay',2,'_CUSTOMTASKSPRE','DISPLAY: custom pre-session tasks');
aline[2]='<input type="button" value="<PANEL> : Custom pre-session (written under the generic tasks)" onClick="'+tmp+'" /> ';

tmp=makeFuncCall('showStuffDisplay',3,'_CUSTOMTASKS1','DISPLAY: custom tasks ');
aline[3]='<input type="button" value="<PANEL> : Custom tasks 1  (written below the generic tasks)" onClick="'+tmp+'" /> ';

tmp=makeFuncCall('showStuffDisplay',4,'_CUSTOMTASKS2','DISPLAY: more custom tasks ');
aline[4]='<input type="button" value="<PANEL> : Custom tasks 2 (written below custom tasks 1)" onClick="'+tmp+'" /> ';

tmp=makeFuncCall('showStuffDisplay',5,'_LOADCUSTOMPARAMSUSE','DISPLAY: custom parameter modification screen');
aline[5]='<input type="button" value="<PANEL> : Custom parameter modification screen (used in generic task ii)" onClick="'+tmp+'" /> ';

for (var m=1;m<aline.length;m++) {
  stuff2=stuff2+'\n <tr><td> '+aline[m]+'</td><td><span id="displayOthers'+m+'" />  </td></tr> ';
}
stuff2=stuff2+'</table></div>';
currentTaskDisplay(2,stuff2);


// 4th: <DO> components

doList=E2_getNodes(controlNode,'DO');

aline=[]; stuff2='';
aline[0]='<table><tr><th><a href="#" onClick="displayDiv(\'showdos\');return false;" title="click to display the <DO>s "> &lt;do&gt;</a></th> \n  ';
aline[1]='<td> Total of '+doList.length+' &lt;do&gt;s ' +
        ' <div id="showdos" style="display:none"> '+
        '<ul> ' ;
for (var m=0;m<doList.length;m++) {
  doname=getAttributes(doList[m],'name','');
  if (strip(doname)==='') {
        alert('Error: <DO> without a name: '+m);
        return 0;
  }
   amess=getAttributes(doList[m],'message','');
  tmp0=makeFuncCall('showStuffDo',m,doname);
  tmp1='<input type="button" value="'+doname+'" onClick="'+tmp0+'" /> ';
  doListRef[strip(doname).toUpperCase()]=tmp1;
  aline[m+2]='<li>'+tmp1+' <em>'+amess+'</em> ';
}
for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}
stuff2=stuff2+"</ul></div></td></tr></table>" ;
 currentTaskDisplay(2,stuff2);


// 5th: <FORM> components

formList=E2_getNodes(controlNode,'FORM');

aline=[]; stuff2='';

stuff2='<table rules="rows"><tr><th><a href="#" onClick="displayDiv(\'showforms\');return false;" title="click to display the <FORM>s"> &lt;form&gt;</a></th> \n  ';
stuff2=stuff2+'<td> Total of '+formList.length+' &lt;form&gt;s  '+
        '<div id="showforms" style="display:none">' +
        '<table> ';

for (var m=0;m<formList.length;m++) {
  doname=getAttributes(formList[m],'name','');
  if (strip(doname)==='') {
        alert('Error: <FORM> without a name: '+m);
        return 0;
  }
  amess=getAttributes(doList[m],'message','');
  tmp=makeFuncCall('showStuffForm',m,doname);
  tmp1='<input type="button" value="'+doname+'" onClick="'+tmp+'" /> ';
  formListRef[strip(doname).toUpperCase()]=tmp1;
  aline[m]='<tr><td>'+tmp1+' <em>'+amess+'</em></td><td> <span id="displayFormOthers'+m+'" /> </td></tr> ';
}
for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}
stuff2=stuff2+"</table></td></tr></table>" ;
 currentTaskDisplay(2,stuff2);

// 6th: <INCLUDES> components

//includeFiles.length
aline=[]; stuff2='';
aline[0]='<table><tr><th><a href="#" onClick="displayDiv(\'showincludes\');return false;" title="click to display the included files "> &lt;include&gt;</a></th> \n  ';
aline[1]='<td>  Total of '+includeFiles.length+' included files  '+
        '<div id="showincludes" style="display:none;margin-left:10px">' +
        '<ul> ';
for (var m=0;m<includeFiles.length;m++) {
  doname=includeFiles[m];
  amess='';
  tmp=makeFuncCall('showStuffIncludes',m,doname);
  tmp1='<input type="button" value="'+doname+'" onClick="'+tmp+'" /> ';
  aline[m+2]='<li>'+tmp1+' <em>'+amess+'</em> ';
}
for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}
stuff2=stuff2+"</ul></div></td></tr></table>" ;
 currentTaskDisplay(2,stuff2);


return 1 ;
}



//======================
// MODIFY CONTROL FILE
/* ======================================================================= */
 
function goCModifyA(usenam) {
 var toget ;
 if (arguments.length<1) {                      // reload xml files call?
     close_moveBox(0);
     close_moveBox(1);

     toggleDisplay('showTextBoxId0',0);
     usenam=workingInstrument ;
 }
  toggleDisplay('doModify',0);
  var toget=getControlXML_1.replace(/\$NAME\$/g,usenam) ;
  workingInstrument=usenam ;
    Get_xmlFile(toget,['controlNode','','1'],'retrieving a Control file ','goCModifyB',usenam,1) ;
    return 1 ;

}

// =====================================
// this is called after control file is gotten
function goCModifyB(usenam,useopen) { 
var  tmp,tmp1,theSubs;
var m,i1,foo,afile;
var aname,aline,stuff2,tmp;

// got control file
if (useopen==1) {

  updateStatus('Control file retrieved for '+usenam,1);

 foo=controlNode.getElementsByTagName('INCLUDE');

 if (foo.length==0) {
    alert('Error: no <INCLUDE> of control file (perhaps this instrument was not created using the create-an-instrument tool?  (nodes in controlNode=' +controlNode.childNodes.length);
    return 1;
 }
 includeFiles=[];
 for (m=0;m<foo.length;m++) {
     afile=getAttributes(foo[m],'file','');
     if (afile=='')  continue ;
     afile=strip(afile).toUpperCase();

     i1=afile.indexOf('CONTROL_GENERIC.XML');
     if (i1>-1) {
        isControl=1 ;
     } else {
       i1=afile.indexOf('CONTROLOE_GENERIC.XML');
       if (i1>-1) {
          isControl=2 ;
       } else {
          includeFiles[includeFiles.length]=afile;        

       }
    }                   // if
 }                     // for
 if (isControl==0) {
    alert('Error:  <INCLUDE> of control file does not point to CONTROL_GENERIC or CONTROLOE_GENERIC  ');
    return 1;
 }
 onInclude=-1;
 goCModifyB(usenam,2) ;
 return 1;
}
 
if (useopen==2) {
  if (onInclude>-1) {
     if (includeNodeErr==200) {
        includeFilesContent[onInclude]=includeNodeInc ;
     } else {
        alert('Warning ... include file not found on server='+includeFiles[onInclude]);
        includeFilesContent[onInclude]=0 ;
     }
  }
  onInclude++;
  if (onInclude<includeFiles.length) {
    afile=includeFiles[onInclude];
    if (afile.indexOf('/')<0) {
      afile=getParamsXML.replace(/\$NAME\$/g,usenam)+afile ;
    }
    afile=afile.replace(/~/g,'');
    Get_xmlFile(afile,['includeNodeInc','includeNodeErr','1'],'retrieving a control file include file ','goCModifyB',usenam,2) ;
    return 1 ;
  } else {
        updateStatus(' Number of include files read= '+includeFiles.length);
  }

}



//::::  Control

  toggleDisplay('showTextBoxControls',1,'inline');
  defaultCheckUse=0;                    // by default, do NOT buttonize a USE attribute
  enableTextSave=1;                     // do  allow saveing of stuff in text box

 tmp1='<div class="displayFiles"> <h4>Edit the control file, and its components</h4> ' +
      ' <a  title="Click here to view the entire control panel program file " ' +
      ' href="#" onClick="showControlFile(1,0); return false">view the entire control file</a></div> ';
 currentTaskDisplay(tmp1);
 currentTaskDisplay(1);

 tmp="xmlToSave='control'; "+makeFuncCall('showControlFile','1 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
 tmp1='<input type="button" title="Click here to edit CONTROL file " value="CONTROL" onClick="'+tmp+'" />' ;
 tmp1=tmp1+'<em> Use this to remove components, or to add or edit a &lt;SUB&gt; or an &lt;INCLUDE&gt;</em> <hr />';
 currentTaskDisplay(2,tmp1);




//  pullout <SUB> stuff 
subList={};
theSubs=E2_getNodes(controlNode,'sub');
for (var m=0;m<theSubs.length;m++) {
  aname=getAttributes(theSubs[m],'name','');
  aname=strip(aname).toUpperCase();
  if (aname==='') {
        alert('Error: <SUB> without a name...: '+m);
        return 1;
  }
  subList[aname]=theSubs[m];
}

aline=[];
stuff2=' ';
aline[0]='<table><tr><th style="margin-right:15px"><a title="click to edit the three <SET> components" href="#" ' +
          ' onClick="displayDiv(\'showsets\');return false;">&lt;set&gt;</a></th> \n ';
tmp=makeFuncCall('editStuffSub','_INITSET','INIT: initializing variables') ;

aline[1]=' <td ><em>There are three pre-defined actions you can &lt;set&gt; .. </em> ' +
           '<div id="showsets" style="display:none;padding-left:15px; margin-left:14px" >' +
           '<ul> ';

aline[2]='<li><input type="button" value="<SET> Initialize variables"  onClick="'+tmp+'"  /> ';
tmp=makeFuncCall('editStuffSub','_INITDO','INIT: running a DO when the control panel starts');
aline[3]='<li><input type="button" value="<SET> Call a <DO> when control-panel loaded"  onClick="'+tmp+'"  /> '; 
tmp=makeFuncCall('editStuffSub','_INITLOAD','INIT: loading javascript libraries ');
aline[4]='<li><input type="button" value="<SET> LOAD a custom library"  onClick="'+tmp+'" /> ';
aline[5]='</ul></div></td></tr></table> ';

for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}

 currentTaskDisplay(2,stuff2);

// 3.1: <attributes>    

tmp=makeFuncCall('editStuffAttributes','_CUSTOMATTRIBUTES','ATTRIBUTES for control panel elements');
stuff2='<input type="button" value="<ATTRIBUTES> " title="Edit ATTRIBUTES assigned to control panel elements" onClick="'+tmp+'" /> ';
 currentTaskDisplay(2,stuff2);

// 3.2: <PANEL> components
aline=[]; 
stuff2='<table rules="rows"><tr><th><a href="#" onClick="displayDiv(\'showdisplays\');return false;" ' +
        ' title="click to edit the five <PANEL> components"> &lt;panel&gt;</a></th> \n  ';


stuff2=stuff2+'<td><em>The control-panel contains 5 pre-defined areas (on the browser screen) ' +
              ' that are used to display content .. </em>  ' +
              ' <input type="button" onClick="displayDiv(\'customDetails\')" value="?" title="details" /> '  ;

stuff2=stuff2+'\n <div id="customDetails" style="display:none;margin:5px 10% 5px 10%;background-color:#effeef" > '+
     ' <br/>   Details on the five pre-defined areas: ' +
     '<ul> ' +
     ' <li> <tt>Task header</tt> This is typically a short description. It is written near the top of the screen ' +
            ' (above the default tasks table, and below the <em>Control panel</em>  header,  </li> ' +
      '<li><tt>Custom pre-session tasks </tt> These are written under the default pre-session tasks. When the default pre-sessions tasks '+
          ' are hidden, so are these custom pre-session tasks. Which also means that they will be hidden when the <em>Control panel</em>  header is clicked ' +
        '</li> ' +
      '<li><tt>Custom session tasks 1 </tt> These are written below the generic-tasks. ' +
        ' These will be hidden when the <em>Control panel</em>  header is clicked</li> ' +
      '<li><tt>Custom session tasks 2 </tt> These are written below  <tt>custom session tasks 1</tt>. ' +
         ' These will <b>not</b> be hidden when the <em>Control panel</em>  header is clicked</li> ' +
      '<li><tt>Custom parameter modification screen</tt> ' +
         'This is used by the <u>Load scenario/modify parameters</u> pre-session task. ' +
        '</li> ' +
      '</ul> \n ' +
    ' </div>';

 stuff2=stuff2+'<br/> <table id="showdisplays" style="display:none">';

tmp=makeFuncCall('editStuffPanel','_TASKHEADER','DISPLAY: Task Header');
aline[1]='<input type="button" value="<PANEL> : Task Header" onClick="'+tmp+'" /> ';

tmp=makeFuncCall('editStuffPanel','_CUSTOMTASKSPRE','DISPLAY: custom pre-session tasks');
aline[2]='<input type="button" value="<PANEL> : Custom pre-session " onClick="'+tmp+'" /> ';

tmp=makeFuncCall('editStuffPanel','_CUSTOMTASKS1','DISPLAY: custom tasks ');
aline[3]='<input type="button" value="<PANEL> : Custom session tasks 1" onClick="'+tmp+'" /> ';

tmp=makeFuncCall('editStuffPanel','_CUSTOMTASKS2','DISPLAY: more custom tasks ');
aline[4]='<input type="button" value="<PANEL> : Custom session tasks 2" onClick="'+tmp+'" /> ';

tmp=makeFuncCall('editStuffPanel','_LOADCUSTOMPARAMSUSE','DISPLAY: custom parameter modification screen');
aline[5]='<input type="button" value="<PANEL> : Custom parameter modification screen " onClick="'+tmp+'" /> ';


for (var m=1;m<aline.length;m++) {
  stuff2=stuff2+'\n <tr><td> '+aline[m]+'</td><td><span id="displayOthers'+m+'" />  </td></tr> ';
}
stuff2=stuff2+'</table>';
 currentTaskDisplay(2,stuff2);




// 4th: <DO> components

doList=E2_getNodes(controlNode,'DO');


stuff2='<table><tr><th style="padding-right:12px"><a href="#" onClick="displayDiv(\'showdos\');return false;" ' +
       ' title="click to edit the <DO>s "> &lt;do&gt;</a> </th> \n  ';
stuff2=stuff2+'<td style="padding-left:5px"> Total of '+doList.length+' &lt;do&gt;s '+
        '<div id="showdos" style="display:none;margin-left:15px"> ' +
        '<input style="padding-left:10px;background-color:cyan" onClick="doAllEdit(1)" type="button" value="edit all the <DO>s" /> ' ;

aline=[]; 

for (var m=0;m<doList.length;m++) {
  doname=getAttributes(doList[m],'name','');
  if (strip(doname)==='') {
        alert('Error: <DO> without a name: '+m);
        return 0;
  }
  amess=getAttributes(doList[m],'desc message summary','');
  tmp0=makeFuncCall('editStuffDo',m,doname);
  tmp1='<input type="button" value="'+doname+'" onClick="'+tmp0+'" title="'+amess+'" /> ';
  doListRef[strip(doname).toUpperCase()]=tmp1;
  aline[m]=tmp1 ;
}

tmp0= makeFuncCall('editStuffDo',-1,'DO');
aline[aline.length]='<span onClick="'+tmp0+'"   class="newThing" title="Add a new <DO>">New &lt;DO&gt;</span>';

stuff2=stuff2+'<br/>'+makeATable(aline,4,'',0,' cellPadding="8" ');

//for (var m=0;m<aline.length;m++) {
//  stuff2=stuff2+'\n '+aline[m];
//}
//stuff2=stuff2+' </table> \n ' ;

stuff2=stuff2+"</div> </td></tr></table> " ;
 currentTaskDisplay(2,stuff2);

// 5th: <FORM> components

formList=E2_getNodes(controlNode,'FORM');

aline=[]; stuff2='';

stuff2='<table rules="rows"><tr><th><a href="#" onClick="displayDiv(\'showforms\');return false;" ' +
       ' title="click to edit the <FORM>s"> &lt;form&gt;</a></th> \n  ';


stuff2=stuff2+'<td style="padding-left:5px"> Total of '+formList.length+' &lt;form&gt;s  '+
        '<div id="showforms" style="display:none;margin-left:15px"> ' +
        '<input style="padding-left:10px;background-color:cyan" onClick="formAllEdit(1)" type="button" value="edit all the <FORM>s" /> ' ;

for (var m=0;m<formList.length;m++) {
  doname=getAttributes(formList[m],'name','');
  if (strip(doname)==='') {
        alert('Error: <FORM> without a name: '+m);
        return 0;
  }
  amess=getAttributes(doList[m],'desc message','');
  tmp=makeFuncCall('editStuffForm',m,doname);
  tmp1='<input type="button" value="'+doname+'" onClick="'+tmp+'" title="'+amess+'"  /> ';
  formListRef[strip(doname).toUpperCase()]=tmp1;
  aline[m]=tmp1+'<span id="displayFormOthers'+m+'" /> ';
}

tmp0= makeFuncCall('editStuffForm',-1,'FORM');
aline[aline.length]='<span onClick="'+tmp0+'"   class="newThing" title="Add a new FORM">New &lt;FORM&gt;</span>';


stuff2=stuff2+makeATable(aline,4,'',0,' cellPadding="8" ');

stuff2=stuff2+"</div></td></tr></table>" ;

 currentTaskDisplay(2,stuff2);


// 6th: <SUB> components

subListCustom=[] ;
for (var m=0;m<theSubs.length;m++) {
  aname=theSubs[m].getAttribute('name');
  if (aname.substr(0,1)!=='_') {
        subListCustom=subListCustom.concat(m);   // pointer to sublist
  }
}  

aline=[]; stuff2='';

stuff2='<table rules="rows"><tr><th><a href="#" onClick="displayDiv(\'showsubs\');return false;" ' +
       ' title="click to edit the <SUB>s"> &lt;sub&gt;</a></th> \n  ';


stuff2=stuff2+'<td style="padding-left:5px"> Total of '+subListCustom.length+' &lt;sub&gt;s  '+
        '<div id="showsubs" style="display:none;margin-left:15px"> ' +
        '<input style="padding-left:10px;background-color:cyan" onClick="subAllEdit(1)"  ' +
        ' type="button" value="edit all the <SUB>s" /> ' ;


for (var m=0;m<subListCustom.length;m++) {
  doname=getAttributes(theSubs[subListCustom[m]],'name','');
  if (strip(doname)==='') {
        alert('Error: <SUB> without a name .... : '+m);
        return 0;
  }
  amess=getAttributes(theSubs[subListCustom[m]],'desc message','');
  tmp=makeFuncCall('editStuffSub',doname,amess);
  tmp1='<input type="button" value="'+doname+'" onClick="'+tmp+'" title="'+amess+'"  /> ';
  subListRef[strip(doname).toUpperCase()]=tmp1;
  aline[m]=tmp1+'<span id="displaySubOthers'+m+'" /> ';
}

tmp0= makeFuncCall('editStuffSub',-1,'SUB');
aline[aline.length]='<span onClick="'+tmp0+'"   class="newThing" title="Add a new SUB">New &lt;SUB&gt;</span>';

stuff2=stuff2+makeATable(aline,4,'',0,' cellPadding="8" ');

stuff2=stuff2+"</div></td></tr></table>" ;

 currentTaskDisplay(2,stuff2);



// 7th: <INCLUDES> components

//includeFiles.length
aline=[]; stuff2='';
aline[0]='<table><tr><th><a href="#" onClick="displayDiv(\'showincludes\');return false;" ' +
         ' title="click to edit the included files "> &lt;include&gt;</a></th> \n  ';
aline[1]='<td>  Total of '+includeFiles.length+' included files '+
        '<div id="showincludes" style="margin:left:10px;display:none"> ' +
        '<ul> ';
for (var m=0;m<includeFiles.length;m++) {
  doname=includeFiles[m];
  amess='';
  tmp=makeFuncCall('editStuffIncludes',m,doname);
  tmp1='<input type="button" value="'+doname+'" onClick="'+tmp+'" /> ';
  aline[m+2]='<li>'+tmp1+' <em>'+amess+'</em> ';
}
for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}
stuff2=stuff2+"</ul></div></td></tr></table>" ;
 currentTaskDisplay(2,stuff2);



return 1;

}


//==============
// edit ALL the <do>s

function doAllEdit(todo,newstuff) {
var zoob,m,iadd=0,anew;


var stuff='';
if (todo==1) {

   xmlToSave='doAllEdit '; 

   zoob=controlNode.childNodes ;
   for (var m=0;m<zoob.length;m++) {
      if (zoob[m].nodeName.toUpperCase()=='TARGETDO') {
         iadd=1;
         continue;
      }
      if (zoob[m].nodeName.toUpperCase()=='TARGETDO_END') {
        iadd=0;
        continue ;
      }

      if (iadd==1) {
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
  }

  showSomeStuff('',stuff,['Current Instrument specific DOs ','(edit ALL DOs)'],'0 YESTEXT');
 location.hash="textBoxHash";
  return 1;

}

// todo=2: replace prior DO with string in newstuff
 zoob=controlNode.childNodes ;
 iadd=1;

 for (var m=0;m<zoob.length;m++) {

      if (zoob[m].nodeName.toUpperCase()=='LASTMODIFIED') continue ;

      if (zoob[m].nodeName.toUpperCase()=='TARGETDO') {
         anew='<TARGETDO note="do not delete this, it is used by a dSurvey editor" desc="(top of DO)"  ';
         anew=anew+' Modified="'+svy_currentTime(2,2)+'"  />  ';
         stuff=stuff+anew+'\n\n';
         stuff=stuff+strip(newstuff)+'\n\n' ;
         iadd=0;
         continue ;
      }
      if (zoob[m].nodeName.toUpperCase()=='TARGETDO_END') {
         stuff=stuff+'\n\n<TARGETDO_END  note="do not delete this, it is used by a dSurvey editor"  desc="(end of DO)" /> \n';
         iadd=1;
         continue ;
      }
      if (iadd==1)   {                          // not a <custom node, and not in the replaced sections
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
}

return stuff;

}



//==============
// edit ALL the <sub>s

function subAllEdit(todo,newstuff) {
var zoob,m,iadd=0,anew;


var stuff='';
if (todo==1) {    


   xmlToSave='subAllEdit '; 

   zoob=controlNode.childNodes ;
   for (var m=0;m<zoob.length;m++) {
      if (zoob[m].nodeName.toUpperCase()=='TARGETSUB') {
         iadd=1;
         continue;
      }
      if (zoob[m].nodeName.toUpperCase()=='TARGETSUB_END') {
        iadd=0;
        continue ;
      }

      if (iadd==1) {
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
  }

  showSomeStuff('',stuff,['Current Instrument specific sub ','(edit ALL SUBs)'],'0 YESTEXT');
 location.hash="textBoxHash";
  return 1;

}

// todo=2: replace prior SUB with string in newstuff
 zoob=controlNode.childNodes ;
 iadd=1;

 for (var m=0;m<zoob.length;m++) {

      if (zoob[m].nodeName.toUpperCase()=='LASTMODIFIED') continue ;

      if (zoob[m].nodeName.toUpperCase()=='TARGETSUB') {
         anew='<TARGETSUB note="do not delete this, it is used by a dSurvey editor" desc="(top of SUB)"  ';
         anew=anew+' Modified="'+svy_currentTime(2,2)+'"  />  ';
         stuff=stuff+anew+'\n\n';
         stuff=stuff+strip(newstuff)+'\n\n' ;
         iadd=0;
         continue ;
      }
      if (zoob[m].nodeName.toUpperCase()=='TARGETSUB_END') {
         stuff=stuff+'\n\n<TARGETSUB_END  note="do not delete this, it is used by a dSurvey editor"  desc="(end of SUB)" /> \n';
         iadd=1;
         continue ;
      }
      if (iadd==1)   {                          // not a <custom node, and not in the replaced sections
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
}

return stuff;

}




// ================
// edit ALL the <form>s

function formAllEdit(todo,newstuff) {
var zoob,m,iadd=0,anew;
var stuff='';

if (todo==1) {  

   xmlToSave='formAllEdit '; 

   zoob=controlNode.childNodes ;
   for (var m=0;m<zoob.length;m++) {
      if (zoob[m].nodeName.toUpperCase()=='TARGETFORM') {
         iadd=1;
         continue;
      }
      if (zoob[m].nodeName.toUpperCase()=='TARGETFORM_END') {
        iadd=0;
        continue ;
      }

      if (iadd==1) {
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
  }

  showSomeStuff('',stuff,['Current Instrument specific FORMs ','(edit ALL DOs)'],'0 YESTEXT');
 location.hash="textBoxHash";
  return 1;

}

// todo=2: replace prior FORM with string in newstuff
 zoob=controlNode.childNodes ;
 iadd=1;

 for (var m=0;m<zoob.length;m++) {

      if (zoob[m].nodeName.toUpperCase()=='LASTMODIFIED') continue ;

      if (zoob[m].nodeName.toUpperCase()=='TARGETFORM') {
         anew='<TARGETFORM note="do not delete this, it is used by a dSurvey editor" desc="(top of FORM)"  ';
         anew=anew+' Modified="'+svy_currentTime(2,2)+'"  />  ';
         stuff=stuff+anew+'\n\n';
         stuff=stuff+strip(newstuff)+'\n\n' ;
         iadd=0;
         continue ;
      }
      if (zoob[m].nodeName.toUpperCase()=='TARGETFORM_END') {
         stuff=stuff+'\n\n<TARGETFORM_END  note="do not delete this, it is used by a dSurvey editor"  desc="(end of FORM)" /> \n';
         iadd=1;
         continue ;
      }
      if (iadd==1)   {                          // not a <custom node, and not in the replaced sections
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
}
return stuff;

}



/* ======================================================================= */
/* ===== SPEC FILE VIEWER FUNCTIONS */
/* ======================================================================= */

function goSpecA(usenam) {
 var toget ;
  toggleDisplay('doModify',0);
  var toget=getSpecXML_1.replace(/\$NAME\$/g,usenam) ;
  workingInstrument=usenam ;
// now get basic descriptor xml file and modify it
    Get_xmlFile(toget,['specNode','','1'],'retrieving a SPEC file ','goSpecB',usenam,1) ;
    return 1 ;

}

// =====================================
// this is called after control file is gotten
function goSpecB(usenam,useopen) { 
var innc,nlist,inode,parentn,iii,cnode,goo,toget;
var stuff2,afile,m,i1,i2,foo,adesc2,adesc1,isg ;
var aline,doname,amess,tmp1,aname0,mms,tageneric;
var ageneric,tmp,modFilesNode=0,tmpp,isControl ;
var foundIn,flist;

var nns0,nns,killmes,m,aff,garf0,garf,m0;

// got spec file
if (useopen==1) {

  toggleDisplay('showTextBoxControls',1,'none');
  onModuleFiles=-1;
  moduleFilesContent=[]; moduleList={};
  moduleList['count']=0;
  includeFiles=[];
  onInclude=-1;
  defaultCheckUse=1;                    // by default, buttonize a USE attribute
  enableTextSave=0;                     // do NOT allow saveing of stuff in text box
  origSpecNode=E2_xmlToDomCmt(specNode);     // for displaying spec file
  updateStatus('SPEC file retrieved for '+usenam,1);

 foo=specNode.getElementsByTagName('INCLUDE');

 if (foo.length==0) {
    alert('Error: no <INCLUDE> of SPEC_ELEMENTS file (perhaps this instrument was not created using the create-an-instrument tool? ');
    return 1;
 }

// get list of include files  -- but skip if isGeneric

 isControl=0;
 for (m=0;m<foo.length;m++) {
     afile=getAttributes(foo[m],'file','');
     if (afile=='')  continue ;

     afile=strip(afile).toUpperCase();
     i1=afile.indexOf('SPEC_ELEMENTS.XML');
     if (i1>-1) isControl=1 ;

     isg=getAttributes(foo[m],'isGeneric','0');
     if (isg=='1') continue ;                         // skip if isGeneric

     includeFiles[includeFiles.length]=afile;        
 }                     // for
 if (isControl==0) {
    alert('Error:  No <INCLUDE> of SPEC_ELEMENTS file.');
    return 1;
 }

 onInclude=-1;
 goSpecB(usenam,2) ;            // now GET the include files 
 return 1;
}


// save current, and get next, include file
if (useopen==2) {
  if (onInclude>-1) {
     if (includeNodeErr==200) {
        includeFilesContent[onInclude]=includeNodeInc ;
     } else {
        alert('Warning: an include file was not found on the server='+includeFiles[onInclude]);
        includeFilesContent[onInclude]=0 ;
     }
  }
  onInclude++;
  if (onInclude<includeFiles.length) {
    afile=includeFiles[onInclude];
    if (afile.indexOf('/')<0) {
        if (afile.substr(0,1)=='~') {
              afile=getSpecDefaultsXML_2.replace(/\$NAME\$/g,usenam)+afile.substr(1) ;
        } else {
           afile=getSpecDefaultsXML_1.replace(/\$NAME\$/g,usenam)+afile ;
        }
    }
    Get_xmlFile(afile,['includeNodeInc','includeNodeErr','1'],'retrieving a SPEC include file ','goSpecB',usenam,2) ;
    return 1 ;
  }

  if (onInclude==includeFiles.length) {                 // all include files retrieved so get the specelements file 
    afile='spec_elements.xml'
    if (afile.indexOf('/')<0) {
      afile=getSpecDefaultsXML_1.replace(/\$NAME\$/g,usenam)+afile ;
    }
    Get_xmlFile(afile,['specElementsFile','','1'],'retrieving  spec_elements.xml ','goSpecB',usenam,22) ;
    return 1 ;
  }

}

if (useopen==22) {                      // got spec_elements file. Save pointers using the For attribute
  clist0=E2_getNodes(specElementsFile,'calls')
  if (clist0.length==0) {
        alert('Error: no <CALLS> in spec_elements file ');
        return 1 ;
  }

  clist=E2_getNodes(clist0[0],'call');
  callListNodes=[];  callList={} ;
  for (ic= 0 ;ic<clist.length;ic++) {
     acall=clist[ic];
     afor=getAttributes(clist[ic],'for ','');
     if (afor=='') {
        alert('Error: no FOR in a CALL = ' +clist[ic].innerHTML);
        return 1 ;
     } else {
        afors=getWord(afor);
        for (var icc2=0;icc2<afors.length;icc2++) {
            acall2=strip(afors[icc2]).toUpperCase() ;
            if (typeof(callList[acall2])=='undefined')  callList[acall2]=[];
            callListNodes=callListNodes.concat(clist[ic]);
            callList[acall2]=callList[acall2].concat(callListNodes.length-1);
        }
      }
  }                             // ic


  clist0=E2_getNodes(specElementsFile,'USE')
  if (clist0.length==0) {
        alert('Error: no <USE> in spec_elements file ');
        return 1 ;
  }
  clist=E2_getNodes(clist0[0],'*');
  useList={} ;

  for (ic= 0 ;ic<clist.length;ic++) {
     acall=clist[ic];
     acall2=strip(acall.nodeName).toUpperCase();
     useList[acall2]=clist[ic];
  }

}                       // 22


// get module files
if (useopen==3) {

  if (onModuleFiles>-1) {
    moduleFilesContent[onModuleFiles]=moduleFileNode ;
    mms=moduleFileNode.getElementsByTagName('module');   // parse out modules
    for (var m=0;m<mms.length;m++) {
        mmid=getAttributes(mms[m],'id','');
        if (mmid!='') {
           mmid=strip(mmid).toUpperCase() ; 
           moduleList[mmid]=mms[m];   
           moduleList['count']=moduleList['count']+1 ;
        }
    }
  }

  onModuleFiles++;
  if (onModuleFiles<moduleFiles.length) {
     afile=moduleFiles[onModuleFiles];
    if (afile.indexOf('/')<0) {
      if (afile.substr(0,1)=='~') {
         afile=getModuleXML_2.replace(/\$NAME\$/g,workingInstrument)+afile.substr(1)+'.XML' ;
      } else {
         afile=getModuleXML_1.replace(/\$NAME\$/g,workingInstrument)+afile+'.XML' ;
      }
    }
    Get_xmlFile(afile,['moduleFileNode','','1'],'retrieving a modules file ','goSpecB',afile,3) ;
    return 1 ;

  } else {              // display list of modules
        stuff2='';
        stuff2=stuff2+'\n <table cellpadding="8"><tr><th><a href="#" onClick="displayDiv(\'showmods\');return false;" title="click to display the <MODULES>s "> &lt;modules&gt;</a> </th> \n  ';
        stuff2=stuff2+'\n <td> Total of '+(moduleList['count']-1) +' &lt;module&gt;s <ul id="showmods" style="display:none"> ';
        for (var m in moduleList) {
          if (m=='count') continue ;
          flist=[];
          if (typeof(modulesToGroup[m])!=='undefined') {
            foundIn=modulesToGroup[m];    
            flist=getWord(foundIn,0,',');
          }
          aclick=' onClick="'+makeFuncCall('showAModule',m)+'"' ;
          tmp='\n<li><input type="button" value="'+m+'" title="display this module" '+aclick+ ' /> ';
          stuff2=stuff2+tmp +'<span style="background-color:#aaddee">Found in: '+flist.join(' | ')+'</span>';
       }
       stuff2=stuff2+'</ul></td></tr></table> \n ';
       currentTaskDisplay(2,stuff2);
  } 
  return 1 ;                    // no more module files? then done with specB
}


/*  ----  
 if here, got spec, spec_elements, include filees. Now pull out the important components.
 In INIT
   <SECTIONS 

   <SUB>
Note: after this is done, download module files

----  */


//  pullout <sub> stuff 
subList={};

aline=[];
stuff2='';
theSubs=E2_getNodes(specNode,'sub'); 
for (var m=0;m<theSubs.length;m++) {
  aname0=getAttributes(theSubs[m],'name','');
  aname=strip(aname0).toUpperCase();
  if (aname==='') {
        alert('Error: <SUB> without a name..... '+m);
        return 1;
  }
  subList[aname]=theSubs[m];
  
  adesc=getAttributes(theSubs[m],'desc message summary','');
  ageneric=getAttributes(theSubs[m],'isGeneric','');
  adesc1='<SUB> '+aname0+' :: '+adesc;
  adesc2='SUB '+aname0+' :: '+adesc;
  tageneric=strip(ageneric).toUpperCase();
  if (tageneric=='MODULEFILES') {           // reading module files sub? Then save for use below (showing module files )
         modFilesNode=theSubs[m];
  } else { 
     if (tageneric=='INITIALIZATIONVARS' || tageneric=='SIMPLEHISTORY') {           // display these generic <SUBS>
        tmp=makeFuncCall('showStuffSub',aname,adesc2,ageneric);
        aline[aline.length]=' <li><input type="button" value="'+adesc1+' "  onClick="'+tmp+' " /> ';
     }                           // else, they SUBs will be included where needed 
  }
}


/* now, buttons to view original xml files */
 tmp1='<h4 align="center">View SPEC and module files </h4> \n ';
 tmp1=tmp1+'<div class="displayFiles"><span class="displayFiles2">View original XML files: </span> ';

 tmp1=tmp1+ '<input type="button" title="Click here to view the entire, original, SPEC file " ' +
            ' value="SPEC" onClick="showSpecFile()" />' ;
 tmp=makeFuncCall('showSpecElements',1) ;
 tmp1=tmp1+' <input type="button" title="Click here to view the spec_elements file " ' +
             ' value="SPEC_Elements" onClick="'+tmp+' " /> ';


  if (modFilesNode!==0)  {                     // links to module files
    dd='';
    afile=E2_getNodeText(modFilesNode) ;
    moduleFiles=getWord(afile);

    for (var m=0;m<moduleFiles.length;m++) {
      aclick=' onClick="'+makeFuncCall('showAModuleFile',moduleFiles[m])+'"' ;
      amod='<input type="button" value="'+moduleFiles[m]+'" title="click to display this module file" '+aclick+' > ';
      dd=dd+' '+amod;
    }
    tmp1=tmp1+' '+dd ;
  }

  for (var m=0;m<includeFiles.length;m++) {
     doname=includeFiles[m];
     amess='';
     tmp=makeFuncCall('showStuffIncludes',m,doname);

    if (includeFilesContent[m]==0) {
       tmp1=tmp1+'<span style="background-color:#bcbcbd" title="This include file is missing-- it is NOT on the server" ><tt>'+includeFiles[m]+'</tt></span>';
    } else {
     tmp1=tmp1+'<input type="button" value="'+doname+'" title="View this <include> file" onClick="'+tmp+'" /> ';
    }
  }



 currentTaskDisplay(tmp1);
 currentTaskDisplay(1);

/* -- now, display the special (isGeneric) subs */
stuff2='<table><tr><th><a title="click to display the <SUB>s" href="#" onClick="displayDiv(\'showsets\');return false;">&lt;sub&gt;</a></th> \n ';
stuff2=stuff2+' <td><ul id="showsets" style="display:block">';
for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}
stuff2=stuff2+'</ul></td></tr></table> \n ';
currentTaskDisplay(2,stuff2);


// === resolve the <INCLUDE>

nns0=specNode.getElementsByTagName('INCLUDE');
nns=Concat_Arrays(nns0);
killmes=[];
for (m=0;m<nns.length;m++) {

   isg=getAttributes(nns[m],'isGeneric','0');
   if (isg=='1') continue ;                         // skip if isGeneric

   aff=getAttributes(nns[m],'sub','') ;
   if (aff!=='') {                                 // incldue a SUB
          aname=strip(aff).toUpperCase();
          if (typeof(subList[aname])=='undefined') {
             alert('Error: <INCLUDE SUB> name does not exist: '+aff);
            return 1;
          }
          garf0=subList[aname];
 
          for (var m2=0;m2<garf0.childNodes.length;m2++) {
             garf=E2_xmlToDomCmt(garf0.childNodes[m2]);
             if (garf.setAttribute) garf.setAttribute('fromIncludeSub',aff);
             nns[m].parentNode.insertBefore(garf,nns[m]);
           }
           killmes=killmes.concat(nns[m]);
           continue ;                            // next element
    }               // no sub, perhaps a file?

    aff=getAttributes(nns[m],'file','') ;
    if (aff=='') continue ;                 // not a file, so skip
        
   garf0=getIncludeFile(aff);
   if (garf0!==0) {                         // 404 or other problem
          for (var m2=0;m2<garf0.childNodes.length;m2++) {
             garf=E2_xmlToDomCmt(garf0.childNodes[m2]);
             if (garf.setAttribute) garf.setAttribute('fromIncludeFile',aff);
             nns[m].parentNode.insertBefore(garf,nns[m]);
          }
          killmes=killmes.concat(nns[m]);
    }    else {                                     // nonexistent incldue file
            nns[m].setAttribute('alert','File Not Found!  ');
    }
}
removeNodes(killmes);




// 2: <SECTION> components

doList=E2_getNodes(specNode,'SECTION');

groupList['0']='';
aline=[]; stuff2='';
aline[0]='<table><tr><th><a href="#" onClick="displayDiv(\'showdos\');return false;" title="click to display the <SECTION>s "> &lt;section&gt;</a></th> \n  ';
aline[1]='<td> Total of '+doList.length+' &lt;section&gt;s <ul id="showdos" style="display:none"> ';
for (var m=0;m<doList.length;m++) {
  doname=getAttributes(doList[m],'name','');
  if (strip(doname)==='') {
        alert('Error: <SECTION> without a name: '+m);
        return 0;
  }
  amess=getAttributes(doList[m],'message desc  summary','');
  foo=getAttributes(doList[m],'fromIncludeFile fromIncludeSub','');

  tmp=makeFuncCall('showStuffSection',m,doname,amess);
  if (foo!=='') {
     tmp1='<input type="button" style="border:2px solid yellow" title="view this section, that was <INCLUDE>d from '+foo+'"  value="'+doname+'" onClick="'+tmp+' " /> ';
  } else {
     tmp1='<input type="button" title="view this section" '+m+'" value="'+doname+'" onClick="'+tmp+' " /> ';
  }
  doListRef[strip(doname).toUpperCase()]=tmp1;
  tmp1=tmp1+' <em>'+amess+'</em>';
  ggtmp='<table><tr><td>'+tmp1+'</td><td><span class="descGroups" id="_'+doname+'_'+m+'"></span></td></tr></table>';
  aline[m+2]='<li>'+ggtmp+ '</li> ';


}
for (var m=0;m<aline.length;m++) {
  stuff2=stuff2+'\n '+aline[m];
}
stuff2=stuff2+"</ul></td></tr></table>" ;
 currentTaskDisplay(2,stuff2);


// and write group buttons


for (var m0=0;m0<doList.length;m0++) {

   stuff2a=doList[m0] ;
   nns0=stuff2a.getElementsByTagName("*");
   nns=Concat_Arrays(nns0);

/* ========
   killmes=[];
   for (m=0;m<nns.length;m++) {
       if (strip(nns[m].tagName).toUpperCase()!=='INCLUDE') continue ;
       aff=getAttributes(nns[m],'sub','') ;
       if (aff!=='') {                                 // incldue a SUB
          aname=strip(aff).toUpperCase();
          if (typeof(subList[aname])=='undefined') {
             alert('Error: <INCLUDE SUB> name does not exist: '+aff);
            return 1;
          }
          garf0=subList[aname];
 
          for (var m2=0;m2<garf0.childNodes.length;m2++) {
             garf=E2_xmlToDomCmt(garf0.childNodes[m2]);
             if (garf.setAttribute) garf.setAttribute('fromIncludeSub',aff);
             nns[m].parentNode.insertBefore(garf,nns[m]);
           }
           killmes=killmes.concat(nns[m]);
           continue ;                            // next element
        }               // no sub, perhaps a file?
        aff=getAttributes(nns[m],'file','') ;

        if (aff=='') continue ;                 // not a file, so skip
        garf0=getIncludeFile(aff);
        if (garf0!==0) {                         // 404 or other problem
          for (var m2=0;m2<garf0.childNodes.length;m2++) {
             garf=E2_xmlToDomCmt(garf0.childNodes[m2]);
             if (garf.setAttribute) garf.setAttribute('fromIncludeFile',aff);
             nns[m].parentNode.insertBefore(garf,nns[m]);
          }
          killmes=killmes.concat(nns[m]);
        }    else {                                     // nonexistent incldue file
            nns[m].setAttribute('alert','File Not Found!  ');
        }
   }
   removeNodes(killmes);
====*/

  doname=getAttributes(doList[m0],'name','');

  findGroupList(m0,doname);
}





// 7th: get the modules files
if (modFilesNode===0) return 1 ;
onModuleFiles=-1 ;
moduleList={};
  moduleList['count']=0;
moduleFiles=[];
afile=E2_getNodeText(modFilesNode) ;
moduleFiles=getWord(afile);
goSpecB(usenam,3);


return 1 ;
}


//======================
// MODIFY SPEC ETC FILES
/* ======================================================================= */
 
function goModifyA(usenam) {
 var toget ;

 if (arguments.length<1) {                      // reload xml files call?
     close_moveBox(0);
     close_moveBox(1);

     toggleDisplay('showTextBoxId0',0);
     usenam=workingInstrument ;
 }
  toggleDisplay('doModify',0);
  var toget=getSpecXML_1.replace(/\$NAME\$/g,usenam) ;
  workingInstrument=usenam ;
// now get basic descriptor xml file and modify it
    Get_xmlFile(toget,['specNode','','1'],'retrieving a SPEC file ','goModifyB',usenam,1) ;
    return 1 ;

}

// =====================================
// modify spec file (this is first called after control file is gotten
function goModifyB(usenam,useopen) {
var innc,nlist,inode,parentn,iii,cnode,goo,toget;
var stuff2,afile,m,i1,i2,foo,adesc2,adesc1,isg ;
var aline,doname,amess,aname0,mms,tageneric;
var ageneric,tmp,modFilesNode=0,tmpp,usec ;
var zoob,tmp1,im,bname,bdesc,alist,btype;
var nns0,nns,killmes,m,aff,garf0,garf,m0,inc3,noDo,noDo2,bdescWord='';
var stylesmall,ztmp,newSectionCell,newSubCell ;
var btmp,bnameShow,bdescTitle,btmp2,totalBname=0,ifoo ;

// got spec file, get INCLUDEs
if (useopen==1) {

  toggleDisplay('showTextBoxControls',1,'inline');
  defaultCheckUse=0;                    // by default, do NOT buttonize a USE attribute
  enableTextSave=1;                     // do  allow saveing of stuff in text box
  origSpecNode=E2_xmlToDomCmt(specNode);     // for displaying spec file
  updateStatus('SPEC file retrieved for '+usenam,1);

 foo=specNode.getElementsByTagName('INCLUDE');

 if (foo.length==0) {
    alert('Error: no <INCLUDE> of SPEC_ELEMENTS file (perhaps this instrument was not created using the create-an-instrument tool? ');
    return 1;
 }

// get list of include files  -- but skip if isGeneric

 isControl=0;
 includeFiles=[];
 for (m=0;m<foo.length;m++) {
     afile=getAttributes(foo[m],'file','');
     if (afile=='')  continue ;

     afile=strip(afile).toUpperCase();
     i1=afile.indexOf('SPEC_ELEMENTS.XML');
     if (i1>-1) isControl=1 ;

     isg=getAttributes(foo[m],'isGeneric','0');
     if (isg=='1') continue ;

     includeFiles[includeFiles.length]=afile;        

 }                     // for
 if (isControl==0) {
    alert('Error:  No <INCLUDE> of SPEC_ELEMENTS file.');
    return 1;
 }
 onInclude=-1;
 goModifyB(usenam,2) ;            // now GET the include files 
 return 1;
}


// save contents of include file  -- but skip if isGeneric
if (useopen==2) {

  if (onInclude>-1) {
     if (includeNodeErr==200) {
        includeFilesContent[onInclude]=includeNodeInc ;
     } else {
        alert('Warning:: include file not found on server='+includeFiles[onInclude]);
        includeFilesContent[onInclude]=0 ;
     }
}
//  if (onInclude>-1) includeFilesContent[onInclude]=controlNodeInc ;
  onInclude++;
  if (onInclude<includeFiles.length) {
    afile=includeFiles[onInclude];
    if (afile.indexOf('/')<0) {
        if (afile.substr(0,1)=='~') {
              afile=getSpecDefaultsXML_2.replace(/\$NAME\$/g,usenam)+afile.substr(1) ;
        } else {
           afile=getSpecDefaultsXML_1.replace(/\$NAME\$/g,usenam)+afile ;
        }
       afile=afile.replace(/~/g,'');

    }
    Get_xmlFile(afile,['includeNodeInc','includeNodeErr','1'],'retrieving a specFle include file ','goModifyB',usenam,2) ;
    return 1 ;
  }

  if (onInclude==includeFiles.length) {                 // all include files retrieved so get the specelements file 
    afile='spec_elements.xml'
    if (afile.indexOf('/')<0) {
      afile=getSpecDefaultsXML_1.replace(/\$NAME\$/g,usenam)+afile ;
    }
    Get_xmlFile(afile,['specElementsFile','','1'],'retrieving  spec_elements.xml ','goModifyB',usenam,3) ;
    return 1 ;
  }

}

// parse out module files list
if (useopen==3) {

  moduleFiles=[];
  theSubs=E2_getNodes(specNode,'sub');                    // get <SUB> that contains list of modulefiles 
  for (var m=0;m<theSubs.length;m++) {
     ageneric=getAttributes(theSubs[m],'isGeneric','');
     tageneric=strip(ageneric).toUpperCase();
     if (tageneric=='MODULEFILES') {
         modFilesNode=theSubs[m];           // save for use below (showing module files )
         afile=E2_getNodeText(modFilesNode) ;
         moduleFiles=getWord(afile);
         onModuleFiles=-1 ;
         goModifyB(usenam,31);
         return 1;
     }
    }
  }

// get module files list
if (useopen==31) {
 if (onModuleFiles>-1) moduleFilesContent[onModuleFiles]=moduleFileNode ;
  onModuleFiles++;
  if (onModuleFiles<moduleFiles.length) {
    afile=moduleFiles[onModuleFiles];
    if (afile.indexOf('/')<0) {
      if (afile.substr(0,1)=='~') {
         afile=getModuleXML_2.replace(/\$NAME\$/g,workingInstrument)+afile.substr(1)+'.XML' ;
      } else {
         afile=getModuleXML_1.replace(/\$NAME\$/g,workingInstrument)+afile+'.XML' ;
      }
    }
    Get_xmlFile(afile,['moduleFileNode','','1'],'retrieving a modules file ','goModifyB',afile,31) ;
    return 1 ;
  }
}                                         // no more module files? on to next step


  updateStatus('Include and Modules files retreived',1);

/* now, buttons to view original xml files (do not expand USE) */
 tmp1='<h4 align="center">Modify SPEC and module files, and parameter and library files </h4> \n ';

 tmp1=tmp1+'<div class="displayFiles"><span class="displayFiles2">View original XML files: </span> ';

 tmp=makeFuncCall('showSpecFile','NOTEXT') ;
 tmp1=tmp1+ '<input type="button" title="Click here to view the entire, original, SPEC file " '+
            ' value="SPEC" onClick="'+tmp+'" />' ;
 tmp=makeFuncCall('showSpecElements',1,'NOTEXT') ;
 tmp1=tmp1+' <input type="button" title="Click here to view the spec_elements file " ' +
             ' value="SPEC_Elements" onClick="'+tmp+' " /> ';


 if (moduleFiles.length!==0)  {                     // links to module files
    dd='';
    for (var m=0;m<moduleFiles.length;m++) {
      aclick=' onClick="'+makeFuncCall('showAModuleFile',moduleFiles[m],'notext')+'"' ;
      amod='<input type="button" value="'+moduleFiles[m]+'" title="click to display this module file" '+aclick+' > ';
      dd=dd+' '+amod;
    }
    tmp1=tmp1+' '+dd ;
  }

  for (var m=0;m<includeFiles.length;m++) {
     doname=includeFiles[m];
     amess='';
     tmp=makeFuncCall('showStuffIncludes',m,doname,'notext');
     if (includeFilesContent[m]!==0) {
       tmp1=tmp1+'<input type="button" value="'+doname+'" title="View this <include> file" onClick="'+tmp+'" /> ';
     }
  }

  currentTaskDisplay('....',tmp1);


/* now, buttons to edit original xml files, in the TEXT box */
 tmp='<input type="button" value="vu" onClick="toggleDisplay(\'vuXMLFilesList\')" /> ';
 tmp1='<input type="button" value="ReLoad XML files" title="Reload the XML files (this can be useful after you save an XML file, and then realize you want to make more changes" onClick="goModifyA()" /> ';
 tmp1=tmp1+'<div class="displayFiles"><span class="displayFiles3">Edit XML files: </span>'+tmp;
  tmp1=tmp1+'<div id="vuXMLFilesList" style="display:block"> ';

 tmp1=tmp1+'<ul class="specEtcUL"> ';                  // BEGIN list of buttons (for spec, spec_Elements, etc)



//::::  SPEC 

   tmp="xmlToSave='spec'; "+makeFuncCall('showSpecFile','YESTEXT  NOWINDOW NOLEFT NORIGHT ',1) ;
 tmp1=tmp1+ '<li><input type="button" title="Click here to edit SPEC file " value="SPEC" onClick="'+tmp+'" />' ;

   tmp='xmlToSave=\'specComponent  -1 SUB \' ; ' + makeFuncCall('showSpecComponent',-1,'SUB','(New SUB) ');
 newSubCell=' <span onClick="'+tmp+'"   class="newThing" title="Add a new <SUB>">New &lt;SUB&gt;</span>';
   tmp='xmlToSave=\'specComponent  -1 SECTION \' ; ' + makeFuncCall('showSpecComponent',-1,'SECTION','(new SECTION) ');
 newSectionCell=' <span onClick="'+tmp+'"  class="newThing"  title="Add a new <SECTION>">New &lt;SECTION&gt;</span>';


// zoob=E2_getNodes(origSpecNode,'*');
 zoob=origSpecNode.childNodes ;

 alist=[];
 for (var im=0;im<zoob.length;im++) {
     usec='sBorder';
     if (zoob[im].nodeType==3 || zoob[im].nodeType==8) continue; 

     noDo=0; noDo2=0;
     var ztmp=getAttributes(zoob[im],'isgeneric','0');
     if (ztmp=='1' ) noDo=1;  // skip generic modules
     if (ztmp=='2' || ztmp=="3" || ztmp=="4" || ztmp=="5" || ztmp=="6") {
           noDo=1;  // skip generic modules
           noDo2=ztmp ; // shrink placeholder
           bdescWord=getAttributes(zoob[im],'descword','');
     }

//     if (getAttributes(zoob[im],'isgeneric','')=='1') noDo=1;  // skip generic modules

     btype=zoob[im].nodeName;
     if (btype=='INCLUDE') {
        usec='sBorderInclude';
        usec2='sub';
        bname=getAttributes(zoob[im],'sub','');
        if (bname=='') {
          usec2='file';
          bname=getAttributes(zoob[im],'file','');
        }
        bdesc=getAttributes(zoob[im],'desc summary title','');
        bdesc=' ('+usec2+': '+bdesc+')' ;

    } else {
        bname=getAttributes(zoob[im],'name id file ','['+zoob[im].nodeName+']');
        bdesc=getAttributes(zoob[im],'desc summary title','');
        if (btype=='SUB') usec='sBorderSub';
    }
    if (noDo==0) {
        tmp='xmlToSave=\'specComponent ' +im+' '+bname+'\'; '+ makeFuncCall('showSpecComponent',im,bname,'(Spec component) '+bdesc);
        styleSmall=' ';
    } else {
        tmp='';
        if (noDo2==0) {
           btype='This is a generic component ('+btype+'): so it can NOT be modified a-component-at-a-time!' ;
           styleSmall=' style="font-size:40%;background-color:lime" '; 
        } else {
           btype=' ' ;
           bname=":"+bdescWord+":";
           styleSmall=' style="font-size:100%;background-color:yellow" ';
           
           if (noDo2==4) {
              btype=' ' ;
              bname='?';
              bdesc=E2_getTextNode(zoob[im]);
              styleSmall=' style="margin-bottom:5px;font-size:100%;background-color:gold" ';
           }
        }
    }
    if (noDo2==2)        alist[alist.length]='....'       // start a new row

    if (noDo2==3 ) {
          alist[alist.length]='....'       // finish the row
    } else if (noDo2==5 ) {                      // newSection cell
          alist[alist.length]=newSectionCell;       // add NEW link
    } else if (noDo2==6 ) {                      // newSUb cell
          alist[alist.length]=newSubCell;       // add NEW link
    } else {                                    // an element that can be modified!
//        totalBname=totalBname+bname.length ;
        alist[alist.length]=' <span onClick="'+tmp+'" class="'+usec+'"'+ styleSmall+ '" title="'+btype+': '+bdesc+' ['+im+']">'+bname+'</span>';
    }
 }

 tmp=makeFuncCall('displayDiv','theSpecNodeList');
 tmp1=tmp1+'<span class="abutton" title="view, and edit, components in the SPEC file" onClick="'+tmp+'">vu/edit...</span><div style="display:none" id="theSpecNodeList" class="sBorder0">  ';

 tmp=makeFuncCall('allInstSections',1) ;
 arf=' <span onClick="'+tmp+'" class="sBorderAll" title="Edit all the instrument-specific SECTIONs">sections</span>';

 tmp=makeFuncCall('allInstSubs',1) ;
 arf=arf+' <span onClick="'+tmp+'" class="sBorderAll" title="Edit all the instrument-specific SUBs">subs</span>';

 ifoo=6;
 tmp1=tmp1+arf+'<div style="padding-top:6px"></div>'+ makeATable(alist,[ifoo,'....']);
 tmp1=tmp1+'</div>';

// ::::::::: spec elements 

 tmp= "xmlToSave='spec_elements'; "+makeFuncCall('showSpecElements',1,'YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
 tmp1=tmp1+' <li><input type="button" title="Click here to edit spec_elements file " ' +
           ' value="SPEC_Elements" onClick="'+tmp+' " /> ';

 alist=[];

 zoob=E2_getNodes(specElementsFile,'calls');
 if (zoob.length>0){
    zoob=zoob[0].childNodes ;
    for (var im=0;im<zoob.length;im++) {
       if (zoob[im].nodeType==3 || zoob[im].nodeType==8) continue ;
       bname=getAttributes(zoob[im],'name for ','(<tt>'+zoob[im].nodeName+'</tt>)' );
       bnameShow=bname;
       btmp=getWord(bname);
       bdesc=getAttributes(zoob[im],'desc summary title','');
       bdescTitle=bdesc;
       if (btmp.length>1) {
         bnameShow=btmp[0] ;
         bdescTitle=bdescTitle+' ['+  btmp.join(', ')+' ]';
       }
       if (bname.indexOf('.')>-1) {
         btmp2=bnameShow.split('.');
         bnameShow=btmp2[0]+'. <span style="font-size:80%">'+btmp2[1]+'</span> ';
       }
       if (btmp.length>1) bnameShow=bnameShow+' ... ';
       tmp='onClick="xmlToSave=\'specElementsCall ' +im+' '+bname+'\'; '+ makeFuncCall('showSpecCall',im,bname,bdesc+' (SpecElement Call for '+btmp.join(', ')+') ')+ '"';
       alist[alist.length]='<span '+tmp+' class="sBorderCall" title="CALL: '+bdescTitle+' ['+im+']">'+bnameShow+'</span>';
   }
 }  

 zoob=E2_getNodes(specElementsFile,'use');
 if (zoob.length>0){
    zoob=zoob[0].childNodes ;
    for (var im=0;im<zoob.length;im++) {
       if (zoob[im].nodeType==3 || zoob[im].nodeType==8) continue ;
       bname=zoob[im].nodeName ;
       bdesc=getAttributes(zoob[im],'desc summary title','');
       tmp='onClick="xmlToSave=\'specElementsUse ' +im+' '+bname+'\'; '+ makeFuncCall('showSpecUse',im,bname,'(SpecElement Use) '+bdesc)+ '"';
       alist[alist.length]=' <span '+tmp+' class="sBorder" title="USE: '+bdesc+'">'+bname+'</span>';
    }
 }

 alist[alist.length]='....';

tmp='xmlToSave=\'specElementsCall  -1 CALL \' ; ' + makeFuncCall('showSpecCall',-1,'CALL','(New CALL) ');
alist[alist.length]=' <span onClick="'+tmp+'" class="newThing" title="Add a new <CALL>">New &lt;CALL&gt;</span>';

tmp='xmlToSave=\'specElementsUse  -1 USE \' ; ' + makeFuncCall('showSpecUse',-1,'USE','(New USE) ');
alist[alist.length]=' <span onClick="'+tmp+'"  class="newThing"  title="Add a new <USE>">New &lt; USE&gt;</span>';


 if (alist.length>0) {
    tmp=makeFuncCall('displayDiv','theSpecElementsList');
     tmp1=tmp1+'<span class="abutton" title="edit/view the components in the SPEC_elements file"  onClick="'+tmp+'">vu/edit..</span> '
     tmp1=tmp1+'<div style="display:none" id="theSpecElementsList" class="sBorder0">&lt;call&gt; and &lt;use&gt;';
     tmp1=tmp1+makeATable(alist,[5,'....']);
     tmp1=tmp1+'</div>';
 }


// module files 
 if (moduleFiles.length!==0)  {                     // links to module files
    dd='';
    for (var m=0;m<moduleFiles.length;m++) {
      tmp="xmlToSave='modules "+moduleFiles[m]+"'; "
      tmp=tmp+makeFuncCall('showAModuleFile',moduleFiles[m],'YESTEXT  NOWINDOW NOLEFT NORIGHT ')  ;
      aclick=' onClick="'+tmp+'" ';
      amod='<li><input type="button" value="'+moduleFiles[m]+'" title="click to edit this module file" '+aclick+' > ';
      dd=dd+' '+amod;

//      zoob=E2_getNodes(moduleFilesContent[m],'module');
      zoob=moduleFilesContent[m].childNodes;

      alist=[];
      for (var im=0;im<zoob.length;im++) {
         if (zoob[im].nodeType==3 || zoob[im].nodeType==8) continue;
          bname=getAttributes(zoob[im],'name id file ',zoob[im].nodeName);
          bdesc=getAttributes(zoob[im],'desc summary title','');
          tmp='onClick="xmlToSave=\'aModule ' +m+' '+im+' '+bname+'\'; '+ makeFuncCall('editModule',m,im,bname,'(Module) '+bdesc)+ '"';
          alist[alist.length]=' <span '+tmp+' class="sBorder2" title="'+bdesc+' ['+im+']"> '+bname+' </span>';
      }
      tmp='xmlToSave=\'aModule '+m+' -1 MODULE \' ; ' + makeFuncCall('editModule',m,-1,'MODULE','(New MODULE) ');
      alist[alist.length]=' <span onClick="'+tmp+'"   class="newThing" title="Add a new <MODULE>" >New &lt;MODULE&gt;</span>';

      tmp=makeFuncCall('displayDiv','theModules_'+m); 

      dd=dd+'<span class="abutton" title="edit/view the modules in this file"  onClick="'+tmp+'">vu/edit..</span><div id="theModules_'+m+'"  style="display:none" class="sBorder0">  ';
      dd=dd+makeATable(alist,6);
      dd=dd+'</div>'; 
    }
    tmp1=tmp1+dd;
  }

  for (var m=0;m<includeFiles.length;m++) {
     doname=includeFiles[m];
     tmp="xmlToSave='include "+includeFiles[m]+"'; "
     amess='';
     if (includeFilesContent[m]!==0) {
       tmp=tmp+makeFuncCall('showStuffIncludes',m,doname,'YESTEXT NOWINDOW NOLEFT NORIGHT ');
       tmp1=tmp1+'<li><input type="button" value="'+doname+'" title="Edit this <include> file" onClick="'+tmp+'" /> ';
    } else {
       tmp1=tmp1+'<li><tt>'+includeFiles[m]+' (not available)</tt>';
    }
  }
// create an include file?
  tmp="xmlToSave='include 0 '; ";
  tmp=tmp+makeFuncCall('showStuffIncludes',-1,0,'YESTEXT NOWINDOW NOLEFT NORIGHT ');
  tmp1=tmp1+'<li><input type="button" value="Create a new  INCLUDE file" title="Before clicking here, enter (in the text box) a one-word name for this include file ..." onClick="'+tmp+'" /> ';
  tmp1=tmp1+'<input type="text" size="15" id="newIncludeName" title="Name for a new <INCLUDE> file (for inclusion in the SPEC file)" value="" />';

  tmp1=tmp1+'</ul></div>';


 currentTaskDisplay(2,tmp1);
 currentTaskDisplay(1);


return 1 ;
}


//======================
// edit all the instrument specific sections
function allInstSections(todo,newstuff) {
var zoob,m,iadd=0,anew;
var stuff='';
if (todo==1) {                          // show all instrument specific sections (between CUSTOMSECTIONS_TOP and CUSTOMSECTIONS_END

   xmlToSave='allInstSections '; 

   zoob=origSpecNode.childNodes ;
   for (var m=0;m<zoob.length;m++) {
      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSECTIONS_START') {
         iadd=1;
         continue;
      }
      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSECTIONS_END') {
        iadd=0;
        continue ;
      }
      if (zoob[m].nodeName.toUpperCase()=='SECTIONTARGET') {
        continue ;
      }

      if (iadd==1) {
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
  }

  showSomeStuff('',stuff,['Current Instrument specific sections ','(edit all sections)'],'0 YESTEXT');
 location.hash="textBoxHash";
  return 1;

}

// todo=2: replace prior custom sections with string in newstuff
 zoob=origSpecNode.childNodes ;
 iadd=1;

 for (var m=0;m<zoob.length;m++) {

      if (zoob[m].nodeName.toUpperCase()=='LASTMODIFIED') continue ;

      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSECTIONS_START') {
         anew='<CUSTOMSECTIONS_START isgeneric="2" note="do not delete this, it is used by a dSurvey editor" desc="(top of instrument specific sections)" descword="Sections" ';
         anew=anew+' Modified="'+svy_currentTime(2,2)+'"  />  ';
         stuff=stuff+anew+'\n\n';
         stuff=stuff+strip(newstuff)+'\n\n' ;
         iadd=0;
         continue ;
      }
      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSECTIONS_END') {
         stuff=stuff+'<SECTIONTARGET isgeneric="5" note="do not delete this, it is used by a dSurvey editor" desc="New Section target"/> ';
         stuff=stuff+'\n\n<CUSTOMSECTIONS_END isgeneric="3" note="do not delete this, it is used by a dSurvey editor"  desc="(end of instrument specific sections)" /> \n';
         iadd=1;
         continue ;
      }
      if (iadd==1)   {                          // not a <custom node, and not in the replaced sections
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
}
return stuff;


}


//======================
// edit all the instrument specific subs
function allInstSubs(todo,newstuff) {
var zoob,m,iadd ;
iadd=0;
var stuff='';

if (todo==1) {                          // show all instrument specific sections (between CUSTOMSUB_START and CUSTOMSUB_END

   xmlToSave='allInstSubs '; 
   zoob=origSpecNode.childNodes ;
   for (var m=0;m<zoob.length;m++) {
      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSUBS_START') {
         iadd=1;
         continue;
      }
      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSUBS_END') {
        iadd=0;
        continue ;
      }
      if (zoob[m].nodeName.toUpperCase()=='SUBTARGET') {
        continue ;
      }

      if (iadd==1) {
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
  }

  showSomeStuff('',stuff,['Current Instrument specific SUBs ','(edit all SUBs)'],'0 YESTEXT');
 location.hash="textBoxHash";

  return 1;

}


// todo=2: replace prior custom subs with string in newstuff
 zoob=origSpecNode.childNodes ;
 iadd=1;
 for (var m=0;m<zoob.length;m++) {

      if (zoob[m].nodeName.toUpperCase()=='LASTMODIFIED') continue ;

      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSUBS_START') {
         anew='<CUSTOMSUBS_START isgeneric="2" note="do not delete this, it is used by a dSurvey editor" desc="(top of instrument specific subs)" descword="Subs" ';
         anew=anew+' Modified="'+svy_currentTime(2,2)+'"  /> ';
         anew=anew+' Modified="'+svy_currentTime(2,2)+'"  />  ';
         stuff=stuff+anew+'\n\n';
         stuff=stuff+strip(newstuff)+'\n\n' ;
         iadd=0;
         continue ;
      }
      if (zoob[m].nodeName.toUpperCase()=='CUSTOMSUBS_END') {
         stuff=stuff+'<SUBTARGET isgeneric="6" note="do not delete this, it is used by a dSurvey editor" desc="New SUB target"/> ';
         stuff=stuff+'\n\n<CUSTOMSUBS_END isgeneric="3" note="do not delete this, it is used by a dSurvey editor" desc="(end of instrument specific subs)" /> \n';
         iadd=1;
         continue ;
      }
      if (iadd==1)   {                          // not a <custom node, and not in the replaced sections
        anew=E2_xmlToString(zoob[m]);
        stuff=stuff+anew;
      }
}
return stuff;



}


//======================
// retreive backup files
/* ======================================================================= */
function goRetrieveA(usenam) {

  toggleDisplay('doModify',0);
  toggleDisplay('showTextBoxControls',1,'none');

  var toget=getInstrumentFilesList+'&name='+usenam+'&ext=XML' ;
  workingInstrument=usenam ;
    Get_File(toget,'instFilesString','retrieving list of spec and modules files ','goRetrieveB',usenam,1) ;
    return 1 ;

}

//=======
function goRetrieveB(usenam,ido) {
var atable,atable2,atr,atr2,m,mm,blist,aback,afile2,adir,tt,ftype;
var alist,m,afile,blist,inps,jm,stuff;
if (instFilesString.toUpperCase().substr(0,1)=='-') {
   alert('Error: '+instFilesString);
   return 0;
}
alist=getWord(instFilesString)
if (alist[0]==0)  {
 currentTaskDisplay('','odd -- no files? ');
 currentTaskDisplay(1);
 return 0;
}
stuff='<h4>List of backup files available for instrument '+usenam+'</h4>';
listOfBackups={};
listOfBackups['0']=[];
listOfBackups['1']=[];
for (var m=1;m<alist.length;m++) {
 afile=alist[m];
 listOfBackups['1'][m]=afile ;
 tt=parseAt(afile,'\/');
 adir=tt[0];
 afile1=tt[1];
 if (afile1.indexOf('$')<0) continue ;
 tt=parseAt(afile1,'$');
 aback=strip(tt[0]).toUpperCase();
 afile2=tt[1];

 if (typeof(listOfBackups[aback])=='undefined') {
        listOfBackups[aback]=[];
        listOfBackups['0']=listOfBackups['0'].concat(aback);
 }
 listOfBackups[aback][listOfBackups[aback].length]=[adir,afile2,m];

}

atable='<table rules="rows"><tr style="background-color:#efefef"><th>Backup name</th> ';
  atable=atable+'<td><table cellpadding="10" rules="rows">\n';
  atable=atable+'<tr> <th><em>type of file</em></th><th>  original name</th></tr>\n';
  atable=atable+'</tr></table>';

jm=0;

for (var m=0;m<listOfBackups['0'].length;m++) {
  aback=listOfBackups['0'][m];
  if (aback=='') continue ;
  blist=listOfBackups[aback];
  jm=1-jm;
  atr='<tr class="backupRow'+jm+'"><th rows="'+blist.length+'"> '+aback+'</th>';
  atable2='<table cellpadding="10" rules="rows">\n';
//  atable2=atable2+'<tr> <th><em>type of file</em></th><th>  original name</th></tr>\n';
  for (var mm=0;mm<blist.length;mm++) {
       inps='<span id="restoreButton'+blist[mm][2]+'"><input  type="button" value="restore" title="restore this backup" onClick="restoreBackup(1,'+blist[mm][2]+')" /></span> ';
       inps=inps+'<span  id="deleteButton'+blist[mm][2]+'"><input  type="button" value="delete" title="delete this backup file" onClick="deleteBackup(1,'+blist[mm][2]+')" /></span> ';
       ftype=blist[mm][0];
       if (ftype=='.') ftype='(parameter)';
       atr2='<tr><td><em>'+ftype+'</em></td><td>'+blist[mm][1]+'</td><td>'+inps+'</td></tr>\n'
       atable2=atable2+atr2 ;
  }
  atable2=atable2+'</table>';
  atr=atr+'<td>'+atable2+'</td></tr>\n';
  atable=atable+atr;
}
atable=atable+'</table>\n';

stuff=stuff+atable;

 currentTaskDisplay('',stuff);
 currentTaskDisplay(1);

return 1;
}

/* ======================================================================= */
/* ===== modify parameters file  FUNCTIONS */
/* ======================================================================= */

// retrieve params.xml, reference.xml, allowedUsers.xml 

function goParamsA(usenam) {
 var toget ;
 if (arguments.length<1) {                      // reload xml files call?
     close_moveBox(0);
     close_moveBox(1);

     toggleDisplay('showTextBoxId0',0);
     usenam=workingInstrument ;
 }
 toggleDisplay('doModify',0);

  var toget=getParamsXML.replace(/\$NAME\$/g,usenam)+'params.xml' ;
  workingInstrument=usenam ;
  Get_xmlFile(toget,['paramsNode','paramsCode','1'],'retrieving a SPEC file ','goParamsB',usenam,1) ;
  return 1 ;

}

//======
function goParamsB(usenam,ido) {
var aul,tmp,stuff;

if (ido==1) {
  if (paramsCode!==200) {
     alert('Error reading PARAMS.XML (general parameters) = '+paramsCode);
     return 1;
  }
  updateStatus('PARAMS.XML retrieved ');
  toggleDisplay('showTextBoxControls',1,'inline');

  var toget=getParamsXML.replace(/\$NAME\$/g,usenam)+'reference.xml' ;
  workingInstrument=usenam ;
  Get_xmlFile(toget,['refNode','refCode','1'],'retrieving a SPEC file ','goParamsB',usenam,2) ;
  return 1 ;
}

if (ido==2) {
  if (refCode!==200) {
     alert('Error reading REFERENCE.XML (client-specific reference parameters) = '+refCode);
     return 1;
  }
  updateStatus('REFERENCE.XML retrieved ');

  var toget=getParamsXML.replace(/\$NAME\$/g,usenam)+'allowedUsers.xml' ;
  workingInstrument=usenam ;
  Get_xmlFile(toget,['allowedNode','allowedCode','1'],'retrieving a SPEC file ','goParamsB',usenam,3) ;
  return 1 ;
}

if (ido==3) {
  if (allowedCode!==200) {
     alert('Error reading allowedUsers.XML (allowed users parameters) = '+allowedCode);
     return 1;
  }
  updateStatus('allowedUsers.XML retrieved ');

  var toget=getParamsXML.replace(/\$NAME\$/g,usenam)+'control.xml' ;
  workingInstrument=usenam ;
  Get_xmlFile(toget,['controlNode','controlCode','1'],'retrieving a SPEC file ','goParamsB',usenam,4) ;
  return 1 ;
}

if (ido==4) {
  if (controlCode!==200) {
     alert('Error reading CONTROL.XML (allowed users parameters) = '+controlCode);
     return 1;
  }
  updateStatus('CONTROL.XML retrieved ');

}

stuff='<h4>Choose a parameters file to modify ';
aul='<ul>';

tmp='<input type="button" value="params.xml" title="modify the general parameters file " onClick="modParams(0)" />'
aul=aul+'\n<li>'+tmp;

tmp='<input type="button"  value="reference.xml" title="modify the reference (client-specific) parameters file " onClick="modParams(1)" />'
aul=aul+'\n<li>'+tmp;

tmp='<input type="button"  value="allowedUsers.xml" title="modify the allowed users parameters file " onClick="modParams(2)" />'
aul=aul+'\n<li>'+tmp;

/*
tmp='<input  type="button" value="control.xml" title="modify the control-panel file " onClick="modParams(3)" />'
aul=aul+'\n<li>'+tmp;
*/

aul=aul+'</ul> \n';

stuff=stuff+aul;

stuff=stuff+'\n <div style="margin:10px 5% 10px 5%;font-weight:400"> <em>Hint:</em> '+
  'You can also edit these parameter files using one of the "structured" editors listed under the  '+
  ' <a href="/dsurvey/admin.htm?openCreate=1">Create &amp; modify an instrument</a> option (on the main administrative page). </div>';


 currentTaskDisplay('',stuff);
 currentTaskDisplay(1);

return 1 ;

}

 
//======================
// show a parameters file
function modParams(ido) {

var vnames=['params','reference','allowedUsers','control'];

var vnodes=[paramsNode,refNode,allowedNode,controlNode];

 updateStatus('Selected: '+vnames[ido]);
 xmlToSave=vnames[ido];

 enableTextSave=1;                     // do  allow saveing of stuff in text box

 showSomeStuff('',vnodes[ido],'Modify '+vnames[ido]+' XML file',1+' YESTEXT');
//showSomeStuff('',specElementsFile,adesc,1+' '+nolist,'','',7,['font-weight:700;font-size:120%;border:1px solid blue;margin:15px 0px 5px 0px','color:blue;font-weight:500;font-size:90%','font-weight:400;color:black;font-size:90%'],divExp,spanExp);

return 1 ;


}

/* ======================================================================= */
/* ===== modify lib files (myFunctions.js and myStyles.css)*/
/* ======================================================================= */

function goLibsA(usenam) {
 var toget ;

 if (arguments.length<1) {                      // reload xml files call?
     close_moveBox(0);
     close_moveBox(1);
     toggleDisplay('showTextBoxId0',0);
     usenam=workingInstrument ;
 }
 toggleDisplay('doModify',0);

  var toget=getLibFiles.replace(/\$NAME\$/g,usenam)+'myFunctions.js' ;
  workingInstrument=usenam ;
  Get_File(toget,['jsStuff','jsCode'],'retrieving JS file ','goLibsB',usenam,1) ;
  return 1 ;

}


function goLibsB(usenam,ido) {
 var toget ;
 if (ido==1) {
   if (jsCode!==200) {
        jsStuff='/* Custom functions, for this instrument, can be specified here */ \n ';
    }
  var toget=getLibFiles.replace(/\$NAME\$/g,usenam)+'myStyles.css' ;
  Get_File(toget,['cssStuff','cssCode'],'retrieving CSS file ','goLibsB',usenam,2) ;
  return 1 ;
}

if (ido==2) {
   if (cssCode!==200) {
        cssStuff='/* Custom styles, for this instrument, can be specified here */ \n ';
    }
}


stuff='<h4>Choose a library file to modify ';
aul='<ul>';

tmp='<input type="button" value="myFunctions.js" title="custom javascript functions for this instrument " onClick="modLibs(0)" />'
aul=aul+'\n<li>'+tmp;

tmp='<input type="button" value="myStyles.css" title="custom CSS styles this instrument " onClick="modLibs(1)" />'
aul=aul+'\n<li>'+tmp;


aul=aul+'</ul> \n';
stuff=stuff+aul;
currentTaskDisplay('',stuff);
currentTaskDisplay(1);


return 1 ;
}

//======
function modLibs(ido) {

var i2,stuff1,stuff2,iframeE;

// 0=myfunctions.js, 1=my
var vnames=['myFunctions.js','myStyles.css'];
var vtexts=[jsStuff,cssStuff];

 updateStatus('Selected: '+vnames[ido]);
 xmlToSave=vnames[ido];
  updateStatus('Selected: '+vnames[ido]);
 xmlToSave=vnames[ido];

stuff2=vtexts[ido];

//    stuff2=stuff1.replace(/\&/g,'&amp;');
//    stuff2=stuff2.replace(/\>/g,'&gt;');
//    stuff2=stuff2.replace(/\</g,'&lt;');

  iframeE=document.getElementById('editableBox');
    iframeE.value=stuff2;

    displayDiv("showTextBoxControls",'inline');
    displayDiv('showTextBoxId0','inline')

    i2=document.getElementById('showTextBoxDesc');
    i2.innerHTML='Library file: '+vnames[ido] ;

    displayDiv("showTextBoxDoSave",'inline');
    toggleDisplay("askPreview",1,'none');

    displayDiv("backupNameSpan",'inline');

return 1 ;

}
//======================
// various functions
/* ======================================================================= */


//======================
// delete a backup file for an instrument
function deleteBackup(ido,im) {
var afile,toget;
afile=listOfBackups['1'][im];

if (ido==1) {
  toget=deleteInstrumentFile+'&name='+workingInstrument+'&file='+afile;
  Get_File(toget,'delFileString','deleting an instrument spec or modules file ','deleteBackup',2,im) ;
  return 1 ;
}
currentTaskDisplay(2,'Status of deleting file ('+afile+')='+delFileString);

toggleDisplay('deleteButton'+im,0);
toggleDisplay('restoreButton'+im,0);

return 1;
}

//======================
// restore a backup file for an instrument
function restoreBackup(ido,im) {

var tt,adir,afile1,aback,afile2,origfile,igoo,afileto;

afile=listOfBackups['1'][im];
 tt=parseAt(afile,'\/');
 adir=tt[0];
 afile1=tt[1];

 tt=parseAt(afile1,'$');
 aback=strip(tt[0]).toUpperCase();
 afile2=tt[1];
 if (adir=='.') {
    origfile=afile2;
    afileto=afile.substr(2);
 } else {
    origfile=adir+'/'+afile2;
    afileto=afile;
 }

if (ido==1) {
  igoo=confirm('Are you sure you want to use the '+aback+' backup, and overwrite the current '+afile2+' instrument file? ');
  if (!igoo) return 0 ;

  toget=restoreInstrumentFile+'&name='+workingInstrument+'&file='+afileto+'&dest='+origfile;
//  alert('restore '+toget);
  Get_File(toget,'restoreFileString','restoring an instrument spec or modules file ','restoreBackup',2,im) ;
  return 1 ;
}
currentTaskDisplay(2,'Status of restoring file ('+afile+') to ('+origfile+')='+restoreFileString);
updateStatus('Restoring '+afile+':: '+restoreFileString);



return 1;
}


//======================
// make list of groups in this section
function findGroupList(jth,secname) {
var agg,ggs,m,mincs,ic,chks,mhere,ic2,dword;
var zz,zz2,zz0,aid,vid,aspan,showx,adesc,zz2a,tsecname ;

tsecname=strip(secname).toUpperCase();

agg=doList[jth];
if (typeof(doList[jth])=='undefined') {
  alert('Error: no such Section ' +secname);
  return 1;
}
ggs=E2_getNodes(doList[jth],'group');

//mincs=doList[jth].getElementsByTagName('include');

zz0=[];
for (m=0;m<ggs.length;m++) {
  zz=getAttributes(ggs[m],'name','');
  if (zz!=='') {

   use1=tsecname+'.'+strip(zz).toUpperCase();
   groupList[use1]=ggs[m];  

   groupList['0']=groupList['0']+','+use1;

    zz2=getAttributes(ggs[m],'desc summary message mess','');
    zz2a=zz2.replace("'",'`'); zz2=zz2a;
    if (zz2.length>30) zz2='<br/>'+zz2;
    adesc=' group '+zz+' in section '+secname+' <em>'+zz2+'</em>'; 
    showx=makeFuncCall('showStuffGroup',secname,use1,adesc) ;

    aspan='<span onClick="'+showx+'" class="showAGroup" title="'+zz2a+'">'+zz+'</span> ';
    zz0=zz0.concat(aspan) ;

// add to modules-to-group reference
    chks=ggs[m].getElementsByTagName('modules');
    if (chks.length>0) {
       for (var ic=0;ic<chks.length;ic++) {
          mhere=chks[ic].innerHTML ;
          mhere2=getWord(mhere);
          for (var ic2=0;ic2<mhere2.length;ic2++) {
              dword=strip(mhere2[ic2]).toUpperCase() ;
              if (typeof(modulesToGroup[dword])=='undefined') {
                 modulesToGroup[dword]=use1 ;
              } else {
                 if (modulesToGroup[dword].indexOf(use1)<0)
                     modulesToGroup[dword]=modulesToGroup[dword]+','+use1 ;
              }
           }            // ic2
       }                //ic
    }                   // chks.length
  }                     // zz!=''
}               // ggs.length

aid='_'+secname+'_'+jth;
vid=document.getElementById(aid);
vid.innerHTML='<b>Groups:</b> '+zz0.join('  ');

sectionToGroups[secname]='<b>Groups:</b> '+zz0.join('  ');   // for display in section


return 1;
}



//======================
// make list of groups in this section
function findGroupList(jth,secname) {
var agg,ggs,m,mincs,ic,chks,mhere,ic2,dword;
var zz,zz2,zz0,aid,vid,aspan,showx,adesc,zz2a,tsecname ;

tsecname=strip(secname).toUpperCase();

agg=doList[jth];
if (typeof(doList[jth])=='undefined') {
  alert('Error: no such Section ' +secname);
  return 1;
}
ggs=E2_getNodes(doList[jth],'group');

//mincs=doList[jth].getElementsByTagName('include');

zz0=[];
for (m=0;m<ggs.length;m++) {
  zz=getAttributes(ggs[m],'name','');
  if (zz!=='') {

   use1=tsecname+'.'+strip(zz).toUpperCase();
   groupList[use1]=ggs[m];  

   groupList['0']=groupList['0']+','+use1;

    zz2=getAttributes(ggs[m],'desc summary message mess','');
    zz2a=zz2.replace("'",'`'); zz2=zz2a;
    if (zz2.length>30) zz2='<br/>'+zz2;
    adesc=' group '+zz+' in section '+secname+' <em>'+zz2+'</em>'; 
    showx=makeFuncCall('showStuffGroup',secname,use1,adesc) ;

    aspan='<span onClick="'+showx+'" class="showAGroup" title="'+zz2a+'">'+zz+'</span> ';
    zz0=zz0.concat(aspan) ;

// add to modules-to-group reference
    chks=ggs[m].getElementsByTagName('modules');
    if (chks.length>0) {
       for (var ic=0;ic<chks.length;ic++) {
          mhere=chks[ic].innerHTML ;
          mhere2=getWord(mhere);
          for (var ic2=0;ic2<mhere2.length;ic2++) {
              dword=strip(mhere2[ic2]).toUpperCase() ;
              if (typeof(modulesToGroup[dword])=='undefined') {
                 modulesToGroup[dword]=use1 ;
              } else {
                 if (modulesToGroup[dword].indexOf(use1)<0)
                     modulesToGroup[dword]=modulesToGroup[dword]+','+use1 ;
              }
           }            // ic2
       }                //ic
    }                   // chks.length
  }                     // zz!=''
}               // ggs.length

aid='_'+secname+'_'+jth;
vid=document.getElementById(aid);
vid.innerHTML='<b>Groups:</b> '+zz0.join('  ');

sectionToGroups[secname]='<b>Groups:</b> '+zz0.join('  ');   // for display in section


return 1;
}
  
/* ========= update DIVS (status, etc) functions ============= */


//=================
// update the currentTask div (where forms and current task info is displayed
// header: header (in a 1 line colored div
// content : content 
// includeTime. If specified, include a time stamp at the top
// header special codes: 0= hide currentTask, 1=display currentTask, 2=append to content
// note that currentTask by default is HIDDEN

function currentTaskDisplay(header,content,includeTime) {
 var doappend,afoo,ia;

  if (arguments.length<2) content='';
  if (arguments.length<3) includeTime=0;

// two special codes
  if (strip(header)=='0') {
    toggleDisplay('currentTask',0);
     return 1;
  }
  if (strip(header)=='1') {
     toggleDisplay('currentTask',1);  
     return 1;
  }
  if (strip(header)=='2') {
        doappend=1;
        header='';
  }

  ia=document.getElementById('currentTask');
  afoo='';
  if (includeTime==1)  afoo='<div class="createT">'+ svy_currentTime(2,2)+'</div> /n ';
  if (doappend!==1)    afoo=afoo+'\n <div class="create0">'+header+'</div> \n ';
  if (content!=='')    afoo=afoo+' <div class="create1">'+content+'</div> \n ';

  if (doappend!==1) {
      ia.innerHTML=afoo ;
  } else {
      ia.innerHTML=ia.innerHTML+ '\n' + afoo ;
  }

  return 1 ;

}





//========================================================= 
// save content of text box as text
function saveTextBoxText(ii,ffile) {
var usenam,ii,atype,xmlBase,bakname,goo,myVal,bakfile,vv;
usenam=workingInstrument ;
iis=getWord(xmlToSave);
if (iis.length==1) iis[1]=0;
atype=strip(iis[0]);
alert('in savetette '+atype);

if (atype=='myFunctions.js') afile=getLibFiles.replace(/\$NAME\$/g,usenam)+'myFunctions.js' ;
if (atype=='myStyles.css')  afile=getLibFiles.replace(/\$NAME\$/g,usenam)+'myStyles.css' ;

if (ii==3) {
    currentTaskDisplay(2,'<div style="padding-left:10%">Status of saving: '+ffile+' = '+saveTextResponse+'</div>');
    updateStatus('Status of saving backup: '+ffile+' = '+saveTextResponse) ;
    return 1;
}

if (ii==2) {
    currentTaskDisplay(2,'<div style="padding-left:10%">Status of saving: '+ffile+' = '+saveTextResponse+'</div>');
    updateStatus('Status of saving: '+ffile+' = '+saveTextResponse) ;
}


if (ii==1)  {          //          create backup?

  mm=document.getElementById('nameForBackup');
  bakname=strip(mm.value); bakname=bakname.replace(/\s/g,'_');

  if (bakname!=='' ) {                     // a backup file is desired (suppress if creating new include file
     arf=afile.lastIndexOf('\/');
     if (arf<0) {
        bakfile=bakname+'$'+afile ;
     } else {
        tmp=afile.substr(arf+1);
        bakfile=afile.substr(0,arf+1)+bakname+'$'+afile.substr(arf+1);
     }
    if (atype=='myStyles.css') {
        myVal=cssStuff ;
    } else {
        myVal=jsStuff ;
    }
//     goo=postInstrumentFileHeader+'&name='+workingInstrument+'&file='+bakfile+'&content='+escape(myVal);

    if (atype=='params' || atype=='reference' || atype=='allowedUsers' || atype=="myFunctions.js" || atype=="myStyles.css" ||atype=='modules') {
        goo=postInstrumentFileHeader2+'&todo2=2&name='+workingInstrument+'&file='+bakfile+'&content='+myVal;
    } else {
        goo=postInstrumentFileHeader2+'&todo2=1&name='+workingInstrument+'&file='+bakfile+'&content='+myVal;
    }

alert('dgoog '+goo);
     currentTaskDisplay(2,'<p/><div class="sBorder">Please wait while backup ['+bakfile+'] is saved to the server: for the '+afile+' XML file for instrument '+workingInstrument+'</div>');
//    alert(postFileURL+' ggzoo3 '+goo);
     Post_toServer(postFileURL,goo,'saveTextResponse','posting backup xml file ','saveTextBoxText',2,bakfile);
     return 1;
  }
}


// finally..... save textbox content to new text file!

vv=document.getElementById('editableBox');
daval=vv.value;
myVal='\/* library file for:'+workingInstrument+' ; Modified : '+svy_currentTime(1,1)+'*\/ \n\n '
myVal=myVal+daval+' \n ';

 if (atype=="myFunctions.js" || atype=="myStyles.css") {
     goo=postInstrumentFileHeader2+'&todo2=11&name='+workingInstrument+'&file='+afile+'&content='+myVal;
 } else {
//goo=postInstrumentFileHeader+'&name='+workingInstrument+'&file='+afile+'&content='+escape(myVal);
     goo=postInstrumentFileHeader2+'&name='+workingInstrument+'&file='+afile+'&content='+myVal;
 }
currentTaskDisplay(2,'<p/><div class="sBorder">Please wait while modified version of '+afile+' is saved to the server (for instrument '+workingInstrument+')</div>');
Post_toServer(postFileURL,goo,'saveTextResponse','posting xml file ','saveTextBoxText',3,afile);

return 1 ;
}




//========================================================= 
// save content of text box as xml
// ii: the action
// ffile: where to save
// averify: used for verification (actions 10 and 11), and to select a "next action" link (action 3)


function saveTextBox(ii,ffile,averify) {
var mm,myVal,vv,iis,atype,goo,specName,fileType,foo,imi,aname;
var bakname='',bakfile='';
var tmp,daval,atmp,oof,myverify,afile='',specComp,ii;
var xmlBase='instrument';
var nodeToBack,mfile,iscomp,mm;
var chkname,chkname2,garf,nname,nname2,gotComps,iadd,typeCount,specCompUse;
var itargetDO,itargetFORM,itargetSUB;
var askSpecPage=0;

iis=getWord(xmlToSave);
//alert('iis='+iis);
gotComps=1;
if (iis.length==1) {
   gotComps=0;
} else {
    if (iis.length>1) {
        if (iis[2]==-1 || iis[1]==-1) gotComps=0;
    }
}

//alert(gotComps+' xmxx '+xmlToSave);

//if (iis.length==1) {iis[1]=0; iis[2]=0 }

atype=strip(iis[0]);

specComp=-1; specName='';
nodeToBack=nodeToEdit ;
iscomp=0;
fileType='Spec file ';

if (atype=='spec') {
    xmlBase='specFile';
    afile='specs/spec.xml';
    fileType='Spec file ';
}

if (atype=='allInstSections') {
    xmlBase='specFile';
    afile='specs/spec.xml';
    fileType='Spec file ';
}

if (atype=='allInstSubs') {
    xmlBase='specFile';
    afile='specs/spec.xml';
    fileType='Spec file ';
}

if (atype=='specComponent') {

    iscomp=1;
    fileType='Spec file ';
    xmlBase='specFile';
    nodeToBack=origSpecNode ;
    afile='specs/spec.xml';
    specComp=strip(iis[1]);
    specName=strip(iis[2]);
}

if (atype=='spec_elements') {
    fileType='Spec file ';
    xmlBase='specInclude';
    afile='specs/spec_elements.xml';
}

if (atype=='specElementsUse') {
    fileType='Spec file ';
    iscomp=1;
    xmlBase='specInclude';
    nodeToBack=specElementsFile;
    afile='specs/spec_elements.xml';
    specComp=strip(iis[1]);
    specName=strip(iis[2]);
}

if (atype=='specElementsCall') {
    fileType='Spec file ';
    iscomp=1;
    xmlBase='specInclude';
    nodeToBack=specElementsFile;
    afile='specs/spec_elements.xml';
    specComp=strip(iis[1]);
    specName=strip(iis[2]);
}

if (atype=='include') {
    fileType='Spec include-file ';
    xmlBase='includeFile';
     afile=strip(iis[1]);
     if (afile!=='0' && afile.indexOf('/')<0) {
         afile=getSpecDefaultsXML_1.replace(/\$NAME\$/g,workingInstrument)+afile ;
      }
}

if (atype=='modules') {
    fileType='Module file ';
    xmlBase='modules';
    afile=strip(iis[1]);
    if (afile.indexOf('/')<0) {
      if (afile.substr(0,1)=='~') {
         afile=getModuleXML_2.replace(/\$NAME\$/g,workingInstrument)+afile.substr(1)+'.XML' ;
      } else {
         afile=getModuleXML_1.replace(/\$NAME\$/g,workingInstrument)+afile+'.XML' ;
      }
    }
}

if (atype=='aModule') {
   fileType='Module file ';
   iscomp=1;
   xmlBase='modules';
   mfile=strip(iis[1]);
   afile=moduleFiles[mfile] ;
   if (afile.indexOf('/')<0) {
      if (afile.substr(0,1)=='~') {
         afile=getModuleXML_2.replace(/\$NAME\$/g,workingInstrument)+afile.substr(1)+'.XML' ;
      } else {
         afile=getModuleXML_1.replace(/\$NAME\$/g,workingInstrument)+afile+'.XML' ;
      }
   }
   specComp=strip(iis[2]);
   specName=strip(iis[3]);
   if (afile.indexOf('/')<0)  {
      if (afile.substr(0,1)=='~') {
         afile=getModuleXML_2.replace(/\$NAME\$/g,workingInstrument)+afile.substr(1)+'.XML' ;
      } else {
         afile=getModuleXML_1.replace(/\$NAME\$/g,workingInstrument)+afile+'.XML' ;
      }
   }
   nodeToBack=moduleFilesContent[mfile];
}

if (atype=='params' ) {
    fileType='Parameter file ';
   xmlBase='parameters';
  afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'params.xml' ;
}

if (atype=='reference') {
   fileType='Parameters (reference) file ';
   xmlBase='parameters';
  afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'reference.xml' ;
}


if (atype=='myFunctions.js') {
 arf=saveTextBoxText(1);
 return 1 ;
}

if (atype=='myStyles.css') {
 arf=saveTextBoxText(1);
 return 1 ;
}

if (atype=='control') {
   fileType='Control file ';
    xmlBase='control';
    nodeToBack=controlNode;
   afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'control.xml' ;
}

if (atype=='controlComp') {
   fileType='Control file ';
   specName=iis[2];
   typeCount=-1;                        // used for adding a new DO, etc
   xmlBase='control';
   afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'control.xml' ;
   nodeToBack=controlNode;
  if (iis.length==1) {
        specComp=-1;
  } else {                              // check for matching FORM, SUB, or DO (SUB used for SET, DISPLAY, and ATTRIBUTES)
    iscomp=1;
    itargetDO=-1;
    itargetFORM=-1;
    itargetSUB=-1;
    chkname=strip(iis[1]).toUpperCase();
    chkname2=strip(iis[2]).toUpperCase();
    garf=controlNode.childNodes;
    for (var m=0;m<garf.length;m++) {
       nname=garf[m].nodeName ;
       if (nname==chkname) {
          typeCount=m;
           nname2=getAttributes(garf[m],'NAME','');
           if (strip(nname2).toUpperCase()==chkname2) {
               specComp=m;
           }
        }
        if (nname=='TARGETDO') itargetDO=m ;
        if (nname=='TARGETFORM') itargetFORM=m ;
        if (nname=='TARGETSUB') itargetSUB=m ;
    }

  }
}

if (atype=='controlCompInclude') {
   askSpecPage=2;
   fileType='Control include file ';
   afile=iis[2];
   mm=iis[1];
   xmlBase='controlinc';
    if (afile.indexOf('/')<0) {
      afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+afile ;
    }

  nodeToBack=includeFilesContent[mm];
  specComp=-1;

}

if (atype=='doAllEdit') {
   fileType='Control file ';
    xmlBase='control';
    nodeToBack=controlNode;
   afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'control.xml' ;
}

if (atype=='subAllEdit') {
   fileType='Control file ';
    xmlBase='control';
    nodeToBack=controlNode;
   afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'control.xml' ;
}

if (atype=='formAllEdit') {
   fileType='Control file ';
    xmlBase='control';
    nodeToBack=controlNode;
   afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'control.xml' ;
}


if (atype=='allowedUsers') {
    xmlBase='allowedUsers';
    afile=getParamsXML.replace(/\$NAME\$/g,workingInstrument)+'allowedUsers.xml' ;
}

if (afile==0)  afile=newIncludeName ;

if (afile=='') {
  alert('Error in saveTextBox: afile not set: '+xmlToSave);
   return 0;
}

if (ii==2) {
    currentTaskDisplay(2,'<div style="padding-left:10%">Status of saving: '+ffile+' = '+saveTextResponse+'</div>');
    updateStatus('Status of saving backup: '+ffile+' = '+saveTextResponse) ;
}

if (ii==3) {
    if (iscomp==1) {
       if (specName!=='0') {
          currentTaskDisplay(2,'<div style="padding-left:10%">Status of saving: '+ffile+' (component '+specName+') = '+saveTextResponse+'</div>');
          updateStatus('Status of saving: '+ffile+ ' (component '+specName+')= '+saveTextResponse) ;
       } else {
          currentTaskDisplay(2,'<div style="padding-left:10%">Status of saving: '+ffile+' (adding a new '+iis[1]+') = '+saveTextResponse+'</div>');
          updateStatus('Status of saving: '+ffile+ ' (adding a new '+iis[1]+')= '+saveTextResponse) ;
       }
    } else {
      currentTaskDisplay(2,'<div style="padding-left:10%">Status of saving: '+ffile+' = '+saveTextResponse+'</div>');
      updateStatus('Status of saving: '+ffile+ ' = '+saveTextResponse) ;
    }
    if (averify==1) {
        currentTaskDisplay(2,' <a href="#top" onClick="goModifyA(currentInstName);return false">Do more SPEC, module, etc. file modification?</a> ');
    }
    if (averify==2) {
        currentTaskDisplay(2,' <a href="#top" onClick="goCModifyA(currentInstName);return false">Do more Control file modification?</a> ');
    }

    return 1;
}

if (ii==1  ) {                    // first call -- upload/download to check veracity

 arf=afile.lastIndexOf('\/');
 bakfile=getInstXML+workingInstrument+'/specs/$tmp.xml';

  vv=document.getElementById('editableBox');
  daval=vv.value;
  daval=daval.replace(/\&/g,'&amp;');
  myVal='<?xml version="1.0" encoding="UTF-8" ?>\n\n<instrument>\n';
  myverify=svy_currentTime(1,1);
  myVal=myVal+'<verify value="'+myverify+'" /> \n\n '
  myVal=myVal+daval+'\n\n</instrument> \n ';

  goo=postInstrumentFileHeader2+'&todo2=2&name='+workingInstrument+'&file='+bakfile+'&content='+myVal;

  if (specComp>-1 || iscomp==1) {
     if (specName!=='0') {
        currentTaskDisplay('<p/><div class="sBorder">Please wait for syntax test (file, containing the '+specName+' component, is being uploaded to server: '+afile+'</div>');
    } else {
        currentTaskDisplay('<p/><div class="sBorder">Please wait for syntax test (file, containing a new '+iis[1]+', is being uploaded to server: '+afile+'</div>');
    }
  } else {
     currentTaskDisplay('<p/><div class="sBorder">Please wait for syntax test (file is being uploaded to server: '+afile+'</div>');
  }
  currentTaskDisplay(1);
  updateStatus('Verifying '+atype+' (length='+goo.length+')');
//    alert(postFileURL+' ggzoo2 '+goo);

  Post_toServer(postFileURL,goo,'saveTextResponse','posting temp xml file ','saveTextBox',10,bakfile,myverify);
  return 0;
}

if (ii==10) {                    // after upload to check veracity 
  updateStatus('Syntax test, step 1, complete (test file uploaded to server)',1);

 if (saveTextResponse.substr(0,2)!=='ok') {
        alert('Syntax test failure: Problem uploading file: '+saveTextResponse);
    return 1;
  }
  toget=ffile;
  Get_xmlFile(toget,['testNode','','1'],'retrieving quality check XML ','saveTextBox',11,bakfile,averify) ;

  return 0 ;
}

if (ii==11) {                    // after retrieving the syntax test upload
  oof=E2_getNodes(testNode,'verify');
  if (oof.length==0) {
        alert('Problem with syntax test! ');
        daval=E2_getNodeText(testNode);
        daval=daval.replace(/\</g,'&lt;');
        daval=daval.replace(/\>/g,'&gt;');
        currentTaskDisplay(2,'<div style="background-color:yellow;padding-left:10%">Syntax test FAILURE for: '+bakfile+' :: <br/> '+daval+'</div>');
        updateStatus('Syntax test failure, file NOT saved to server');
        return 1;
  }
  bverify=getAttributes(oof[0],'value','noVerification');
  if (averify!==bverify) {
        alert('Verification failure in syntax test!  Expected='+averify+' || Found='+bverify);
        updateStatus('Syntax test verification failure, file NOT saved to server');
        return 1;
  }
  currentTaskDisplay(2,'<div style="padding-left:10%">Syntax test: PASSED </div>');
  updateStatus('Syntax test complete: (test file retrieved from server)',1);
//alert('arget syntaxt '+atype);
// if allInstSections or allInstSubs, check that each <section> (or <sub>) has a name attribute)
  if (atype=='allInstSections') {
        foo=E2_getNodes(testNode,'section');
        for (var imi=0;imi<foo.length;imi++) {
           aname=getAttributes(foo[imi],'name','');
           if (aname=='') {
                alert('Error: you created a <section> but did not specify a name (the '+(imi+1)+' section)');
                return 0
           }
        }
  }
  if (atype=='allInstSubs') {
        foo=E2_getNodes(testNode,'sub');
        for (var imi=0;imi<foo.length;imi++) {
           aname=getAttributes(foo[imi],'name','');
           if (aname=='') {
                alert('Error: you created a <sub> but did not specify a name (the '+(imi+1)+' sub)');
                return 0
           }
        }
  }
  if (atype=='doAllEdit') {
        foo=E2_getNodes(testNode,'do'); 
        for (var imi=0;imi<foo.length;imi++) {
           aname=getAttributes(foo[imi],'name','');
           if (aname=='') {
                alert('Error: you created a <do> but did not specify a name (the '+(imi+1)+' DO)');
                return 0
           }
        }
  }
  if (atype=='subAllEdit') {
        foo=E2_getNodes(testNode,'sub'); 
        for (var imi=0;imi<foo.length;imi++) {
           aname=getAttributes(foo[imi],'name','');
           if (aname=='') {
                alert('Error: you created a <sub> but did not specify a name (the '+(imi+1)+' DO)');
                return 0
           }
        }
  }

  if (atype=='formAllEdit') {
        foo=E2_getNodes(testNode,'form');
        for (var imi=0;imi<foo.length;imi++) {
           aname=getAttributes(foo[imi],'name','');
           if (aname=='') {
                alert('Error: you created a <form> but did not specify a name (the '+(imi+1)+'  FORM)');
                return 0
           }
        }
  }


  ii=12  ;              // a hack to do next step
}


if (ii==12)  {          //                preview? create backup?

  mm=document.getElementById('savePreview');
  if (mm.checked) {                                     // PREVIEW

     showSomeStuff('',testNode,'Reviewing changes to '+atype+' '+specName,1+' YESWINDOW NOLEFT NOTEXT ');
     atmp=confirm('Do you want post this ('+afile+') to the server? ');
     if (!atmp) return 1 ;
 }

  mm=document.getElementById('nameForBackup');                     // BACKUP?
  bakname=strip(mm.value); bakname=bakname.replace(/\s/g,'_');
}

 close_moveBox(0);
 close_moveBox(1);


toggleDisplay('showTextBoxId0',0);         // turn off displays

if (bakname!=='' && (atype="controlCompInclude" || atype=='aModule' ||  iis[1]!=='0') ) {          // BACKUP: a backup file is desired (suppress if creating new include file
 arf=afile.lastIndexOf('\/');
 if (arf<0) {
        bakfile=bakname+'$'+afile ;
 } else {
    tmp=afile.substr(arf+1);
    bakfile=afile.substr(0,arf+1)+bakname+'$'+afile.substr(arf+1);
 }
  myVal=E2_xmlToString(nodeToBack) ;                    // The original
  myVal=myVal.replace(/\&/g,'&amp;');

  myVal='<?xml version="1.0" encoding="UTF-8" ?>\n'+myVal  ;

  if (atype=='params' || atype=='reference' || atype=='allowedUsers' ) {
    goo=postInstrumentFileHeader2+'&todo2=1&name='+workingInstrument+'&file='+bakfile+'&content='+myVal;
  } else {
    goo=postInstrumentFileHeader2+'&todo2=2&name='+workingInstrument+'&file='+bakfile+'&content='+myVal;
  }
//    alert('gogog '+goo);
  currentTaskDisplay(2,'<p/><div class="sBorder">Please wait while backup ('+bakfile+') is saved to the server: for the '+afile+' XML file for instrument '+workingInstrument+'</div>');
  Post_toServer(postFileURL,goo,'saveTextResponse','posting backup xml file ','saveTextBox',2,bakfile);
  return 1;
}                               // END BACKUP


// finally..... save textbox content to new xml file!


vv=document.getElementById('editableBox');
daval=vv.value;

if (atype=='controlComp') {
   iadd=0;
   askSpecPage=2;   
   specCompUse=specComp ;
   if (iis[1]=='DO' && specComp<0 ) {                   // a new <DO> ?
        daval='\n<DO name="'+newName+'" desc="'+newDesc+'">\n'+daval+'\n</DO>\n ';
        specCompUse=itargetDO ;
        iadd=1;
   }

   if (iis[1]=='SUB' && specComp<0 ) {                   // a new <SUB> ?
        daval='\n<SUB name="'+newName+'" desc="'+newDesc+'">\n'+daval+'\n</SUB>\n ';
        specCompUse=itargetSUB ;
        iadd=1;
   }

   if (iis[1]=='FORM' && specComp<0 ) {                   // a new <FORM> ?
        if (newNoVuTasks==1) {
             daval='\n<FORM  vuTasksTable="NO" name="'+newName+'" desc="'+newDesc+'">\n'+daval+'\n</FORM>\n ';
        } else {
             daval='\n<FORM name="'+newName+'" desc="'+newDesc+'">\n'+daval+'\n</FORM>\n ';
       }
        specCompUse=itargetFORM
        iadd=1;
   }

   if (gotComps==1) {                           // existing component 
      daval=makeStringFromChildren(controlNode,specCompUse,daval,'lastModified',1,iadd);

   } else {                              // new sub or section
      daval=makeStringFromChildren(controlNode,-1,daval,'lastModified',1,iadd);
   }
}

if (atype=='specComponent') {
   askSpecPage=1 ;
   if (gotComps==1) {                           // existing component
      daval=makeStringFromChildren(origSpecNode,specComp,daval,'lastModified',1);
   } else {                              // new sub or section
      daval='\n<'+iis[2]+' name="'+newName+'" desc="'+newDesc+'" >'+daval+' \n</'+iis[2]+'>\n ';
      daval=makeStringFromChildren(origSpecNode,iis[2]+'TARGET',daval,'lastModified',1,2,1);
   }
}


if (atype=='allInstSections') {         // new Instrument-specific sections (can be more than one section)
   askSpecPage=1 ;   
  daval=allInstSections(2,daval);
}

if (atype=='allInstSubs') {     // new Instrument-specific SUBs (can be more than one SUB)
   askSpecPage=1 ;   
   daval=allInstSubs(2,daval);
}


if (atype=='doAllEdit') {     // new Instrument-specific SUBs (can be more than one SUB)
   askSpecPage=2 ;
   daval=doAllEdit(2,daval);
}

if (atype=='subAllEdit') {     // new Instrument-specific SUBs (can be more than one SUB)
   askSpecPage=2 ;
   daval=subAllEdit(2,daval);
}

if (atype=='formAllEdit') {     // new Instrument-specific SUBs (can be more than one SUB)
   askSpecPage=2 ;   
   daval=formAllEdit(2,daval);
}



if (atype=='aModule') {
   askSpecPage=1 ;   
   if (gotComps==1) {                           // existing component
     daval=makeStringFromChildren(nodeToBack,specComp,daval,'lastModified',1);
   } else {                              // new sub or section
      daval='\n<module id="'+newName+'" desc="'+newDesc+'" >\n'+daval+'\n </module> \n ';
      daval=makeStringFromChildren(nodeToBack,specComp,daval,'lastModified',1);
   }
}
  
if (atype=='specElementsCall') {
   askSpecPage=1 ;
   if (gotComps==1) {                           // existing component
      daval=makeStringFromChildren2(specElementsFile,specComp,daval,'lastModified',1,'calls');
   } else {                     // new call
      daval='\n<call for="'+newName+'" desc="'+newDesc+'" >\n'+daval+'\n </call>\n  ';
      daval=makeStringFromChildren2(specElementsFile,specComp,daval,'lastModified',1,'calls');
   }
}

if (atype=='specElementsUse') {
   askSpecPage=1 ;   
   if (gotComps==1) {                           // existing component
       daval=makeStringFromChildren2(specElementsFile,specComp,daval,'lastModified',1,'use');
   } else {                                     // new use
      daval='\n <'+newName+' desc="'+newDesc+'" >\n'+daval+'\n </'+newName+'>  ';
      daval=makeStringFromChildren2(specElementsFile,specComp,daval,'lastModified',1,'use');
   }
} 

// note: if include file, always save entire thing (updating is not supported)

daval=daval.replace(/\&/g,'&amp;');

myVal='<?xml version="1.0" encoding="UTF-8" ?>\n<'+xmlBase+'>\n';
myVal=myVal+'<lastModified  isGeneric="1" >'+fileType+' for:'+workingInstrument+' ; Modified : '+svy_currentTime(1,1)+' </lastModified>\n\n'
myVal=myVal+strip(daval)+'\n\n</'+xmlBase+'> \n ';

if (atype=='params' || atype=='reference' || atype=='allowedUsers' || atype=='modules' || atype=='aModule' ){
    goo=postInstrumentFileHeader2+'&todo2=2&foobar=1&name='+workingInstrument+'&file='+afile+'&content='+myVal;
} else {
    goo=postInstrumentFileHeader2+'&todo2=3&name='+workingInstrument+'&file='+afile+'&content='+myVal;
}
//alert(atype+' g333 '+goo);

// Note: afile is relative to an instrument's main directory
  currentTaskDisplay(2,'<p/><div class="sBorder">Please wait while the modified version of '+afile+' is saved to the server (for instrument '+workingInstrument+')</div>');
//   alert(atype+' gogog2w2 '+goo);

Post_toServer(postFileURL,goo,'saveTextResponse','posting xml file ','saveTextBox',3,afile,askSpecPage);


return 1 ;
}


//============================
// make a string of components in anode, but replace the innards of the ith component with newStuff
// but drop all nodes with tagname of skips
// anode: node to extract children from
// ith: ith child to replace, or to place after
// newStuff: stuff to replace ithChild with
// skips: nodename (first level) to skip
// notext: if 1, do NOT retain text nodes (in level 1)
// putafter : if 1, then ith is the child to put newstuff AFTER (rather then replace), 2 means put before
// ithString : if 1, then match node name to value of daval (rather than use ith node)

function makeStringFromChildren(anode,ith,newStuff,skips,notext,putafter,ithString) {
 var ii,apart,abig,dork,iii,tt,attname,attval,attlist,nname;
 var zoob,dothis ;
 var didit=0;

 if (arguments.length<4) skips='';
 if (arguments.length<5) notext=0;
 if (arguments.length<6) putafter=0;
 if (arguments.length<7)  ithString=0;

 if (ithString!==1) {
      ith=parseInt(ith);
 } else {
      ith=strip(ith).toUpperCase();
 }
 zoob=anode.childNodes;
 abig='';
 skips=strip(skips).toUpperCase();


 for (var ii=0;ii<zoob.length;ii++) { 
    nname=strip(zoob[ii].nodeName).toUpperCase();
    if (nname==skips)    continue ;
    if (notext==1 && zoob[ii].nodeType==3)  continue ;

    dothis=0;
    if (ithString==1) {
        if (nname==ith) dothis++ ;           // only replace if FIRST match!
    } else {              
       if (ii==ith) dothis++;
    }
   if (dothis!==1) {
          apart=E2_xmlToString(zoob[ii]) ;
          if (apart.substr(0,2)!=='\\n') apart='\n'+apart;
          abig=abig+apart ;
    } else {                            // the component to replace, or to put after
           if (putafter==1) {                           // put new stuff after this node
              apart=E2_xmlToString(zoob[ii]) ;
              if (apart.substr(0,2)!=='\\n') apart='\n'+apart;
              abig=abig+apart ;
              abig=abig+'\n'+newStuff+'\n';
              didit=1;

           } else if (putafter==2) {                     // put before
              abig=abig+'\n'+newStuff+'\n';
              apart=E2_xmlToString(zoob[ii]) ;
              if (apart.substr(0,2)!=='\\n') apart='\n'+apart;
              abig=abig+apart ;
              didit=1;

           }  else {                                    // replace contents (retain attributes and nodename

             dork=zoob[ii].attributes; attlist='';
             for (var iii=0;iii<dork.length;iii++) {
                tt=dork[iii];
                attname=tt.nodeName; 
                attval=tt.nodeValue ;
                attlist=attlist+' '+attname+'="'+attval+'" ';
              }
              abig=abig+'\n <'+zoob[ii].tagName+' '+attlist+'> \n '+newStuff+'\n </'+zoob[ii].tagName+'> \n ';        
              didit=1;
           }                      // putafter
    }
 }
 
 if (ith==-1) {                         // append?
       abig=abig+'\n'+newStuff+'\n';
 } else {
      if (didit==0) alert('Error: content not written (unable to find location '+ith)
 }
 return abig ;
} 

//============================
// make a string of components in anode, but replace the innards of the ith component with newStuff
// but drop all nodes with tagname of skips
// anode: node to extract children from
// ith: itn child to replace (or ith child of level2-name to replace)
// newStuff: stuff to replace ithChild with
// skips: nodenames (first level) to skip
// notext: if 1, do NOT retain text nodes (in level 1)
// level2: if specified,  a nodename to replace ith child of 
function makeStringFromChildren2(anode,ith,newStuff,skips,notext,level2) {

 var ii,apart,abig,dork,iii,tt,attname,attval,attlist,nname;
 var zoob,zoob0,ii0
 ith=parseInt(ith);
 level2=strip(level2).toUpperCase();
 zoob0=anode.childNodes;
 abigs=[];
 skips=strip(skips).toUpperCase();
 for (var ii0=0;ii0<zoob0.length;ii0++) { 
    nname=strip(zoob0[ii0].nodeName).toUpperCase(); 
    if (nname==skips) continue ;
    if (notext==1 && zoob0[ii0].nodeType==3) continue ;
    if (nname!==level2) {
          abigs[abigs.length]=E2_xmlToString(zoob0[ii0]) ;
          continue ;
    }                                   // else, this has a component to replace
    abig='\n<'+level2+'> \n ';
    zoob=zoob0[ii0].childNodes;
    for (var ii=0;ii<zoob.length;ii++) {                        // over all of this first level's children...
      nname=strip(zoob[ii].nodeName).toUpperCase();
      if (ii!==ith) {
          apart=E2_xmlToString(zoob[ii]) ;
//          if (apart.substr(0,2)!=='\\n') apart='\n'+apart;
          abig=abig+apart ;
      } else {                            // the component to replace
           dork=zoob[ii].attributes; attlist='';
           for (var iii=0;iii<dork.length;iii++) {
              tt=dork[iii];
              attname=tt.nodeName; 
              attval=tt.nodeValue ;
              attlist=attlist+' '+attname+'="'+attval+'" ';
          }
          abig=abig+'\n <'+zoob[ii].tagName+' '+attlist+'> \n '+newStuff+'\n </'+zoob[ii].tagName+'> \n ';        
      }
    }
// a new call or use?
    if (ith==-1) {                         // append?
        abig=abig+'\n'+newStuff+'\n';
    }

    abigs[abigs.length]=abig+'\n </'+level2+'>\n';
  }
  abig='';
  for (var ii=0;ii<abigs.length;ii++)  abig=abig+abigs[ii]+'\n ';
  return abig ;
} 


//========================================================= ss
// get include file content, given name
function getIncludeFile(aname) {
aname=strip(aname).toUpperCase();
for (m=0;m<includeFiles.length;m++) {
  if (aname!==includeFiles[m]) continue;
  return includeFilesContent[m];
}
alert(' Error: include file not found = '+aname);
return '' ;
}

//=========================================================
// display string in a  new HTML window. if cvt=1, convert <  > and & to entity codes
function  displayInWindow(stuff2,adesc){
  var ww,atoc,cc,m2,z,aname,atype,adesc,goo ;
  if (arguments.length<3) maketoc=0;
  var cc='<!--  '+adesc+ '--> \n ';
  var ww=window.open('','vuXML',"toolbar=0,menubar=0,directories=0,scrollbars=1,resizable=1" );
  ww.document.open('text/html');


  ww.document.writeln(cc+stuff2); 
  ww.document.close();
  ww.focus();
  return 1;
}



//=====================================
// Functions used to display control panel program


//-=====================
// show content in left,right,window, or textarea
// ss: base string (use before content to display
// stuff2a: either a string, or an XML node
// adescs: 2 element array, string description (2nd element is "additonal")
// doexpand: 0= treat as string to be encoded (< replaced with &gt;
//           1 or 2 = a node 
//           0 noYesList = a string
//           2 noYesList = a note
//                       The noYesList is space delimited list tha may contain any or none
//                      of NOTEXT NORIGHT NOLEFT and NOWINDOW; and YESTEXT YESRIGHT YESLEFT YESWINDOW
//                       if any of these NO words appear, suppress display in apporpriate locations
//                       if any of these YES words appear, display in appropriate lcoation
//                       (NOxx trumps YESxx)
//jumpto:  name of element to focus on (for left or right box display) DEPRECATED
// otherinfo: used to modify display of text (ie; to display text as buttons
// sarg1: indentation amount (default: 15px)
// sarg2: array of extra styles for each level (default:['margin-top:15px;','margin-top:5px;'] 
// expDivs: space delimited list of tagnames that may be expanded. Default,or ' ', means "all"
// spanDivs : space delimited list of tagnames that should be displayed witn SPAN Default,or ' ', means "none"
// checkUse: if 1, then add <use> stuff


function showSomeStuff(ss,stuff2a,adescs,doexpand,jumpto,otherInfo,sarg1,sarg2,expDivs,spanDivs,checkUse) {
var useTextBox,useLeftDiv,ii,stuff2,i2,ii,io,useNewWindow,useRightDiv,m,cnode,nns,nns0;
var ab1,ab2,killmes,aff,stuffbuild,oink,oof,sarg2a,taname,aname ;
var m2,m,aword ;
var iframeE,ibn ;
var tjumpto,ih,natt,adesc2,adesc,adesc1,noDoList,tmp,tmp1,fset;
var atoc,anode,atype,adesc,z,m2,alist;

if (arguments.length<4) doexpand='0';             // doexpand=0 means stuff2a is text. 1 means it is a node
if (arguments.length<5) jumpto='';             // DEPRECATED
if (arguments.length<6) otherInfo='';             // doexpand=0 means stuff2a is text. 1 means it is a node
if (arguments.length<7) sarg1=15;       // indentation amount
if (arguments.length<8) sarg2=['margin-top:15px;','margin-top:5px;']  ; // array of styles for levels
if (arguments.length<9) expDivs='';   
if (arguments.length<10) spanDivs=''; 
if (arguments.length<11) checkUse=defaultCheckUse;
 
if (jumpto!=='') {
  alert('Error: Jumpto is non blank:'+jumpto);
  return 1;
}

doexpand=strip(doexpand).toUpperCase() ;
tmp1=getWord(doexpand);
doexpand=tmp1[0];
noDoList={};
for (var m=1;m<tmp1.length;m++) { 
  aword=tmp1[m];
  noDoList[aword]=1;
}


adesc=adescs ;
adesc1=adescs;
if (typeof(adescs)=='object') {
    adesc=adescs[0]+':  '+adescs[1];
    adesc1=adescs[0];                   // used in textbox
}    

io=document.getElementById('openRightDiv');
useRightDiv=0;
if ( (io && io.checked)  || typeof(noDoList['YESRIGHT'])!=='undefined' ) {                 // box checked. But is it suppresed?
   if (typeof(noDoList['NORIGHT'])=='undefined')  useRightDiv=1;
}

io=document.getElementById('openLeftDiv');
useLeftDiv=0;
if ( (io && io.checked)  || typeof(noDoList['YESLEFT'])!=='undefined' ) {                 // box checked. But is it suppresed?
   if (typeof(noDoList['NOLEFT'])=='undefined')  useLeftDiv=1;
}


io=document.getElementById('openTextBox');
useTextBox=0;
if ((io && io.checked) || typeof(noDoList['YESTEXT'])!=='undefined' ) {                 // box checked. But is it suppresed?
   if (typeof(noDoList['NOTEXT'])=='undefined') {
         useTextBox=1;
  } else {
        alert('Sorry: text box is reserved for modifying content (so original XML file will not be displayed there)'); 
  }
}

io=document.getElementById('openNewWindow');
useNewWindow=0;
if ( (io && io.checked)  || typeof(noDoList['YESWINDOW'])!=='undefined' ) {                 // box checked. But is it suppresed?
   if (typeof(noDoList['NOWINDOW'])=='undefined')  useNewWindow=1 ;
}


if (useRightDiv+useLeftDiv+useTextBox+useNewWindow==0) { 
  alert('You did NOT select an area to display content it (use one of the checkboxes at the top of the screen)');
  return 0;
}

if (useNewWindow==1 && stuff2a!==0) {                   // ==== write to new window (assuming a valid node is available)
  if (parseInt(doexpand)!==0) {
      tmp2a=E2_xmlToDomCmt(stuff2a);
      sarg2a=['margin-top:25px;background-color:#cdcecf;padding-left:12x;',
                'margin-top:15px;background-color:#dddedf;padding-left:10px;',
                'margin-top:8px;background-color:#edeeef;padding-left:8px;',
                'margin-top:2px;background-color:#ffffff;border:#ffffff;padding-left:6px;', 
                'margin-top:2px;background-color:#ffffff;border:#ffffff;padding-left:4px;',
               'margin-top:2px;background-color:#ffffff;border:#ffffff;padding-left:2px;']  ;
      atoc=''; 
      z=E2_getNodes(tmp2a,'*');
      atoc='<ol type="i"> \n';
      alist=[]; 
      for (var m2=0;m2<z.length;m2++) {
            anode=z[m2];
            atype=anode.nodeName ;
            aname=getAttributes(anode,'name id file','');
            if (aname=='')aname=atype;
            aname=strip(aname);
            taname=strip(aname).toUpperCase();
            adesc=getAttributes(anode,'desc summary title','');
            tmp1='_ITEM_'+m2 ;
            tmp="arf1=document.getElementById('"+tmp1+"');arf1.focus()";
            var ago='<input name="toTheFirstOnes"  span style="font-size:60%" type="radio" title="click to jump" onClick="setFocusNow(\''+taname+'\')" />';
            alist[alist.length]=ago+'<span style="background-color:#ebebeb;font-size:80%" title="'+atype+' :: '+adesc+'">'+aname+'</span>  ';
      }
      atoc='<div style="margin:0px 12px 0px 12px">  '+adesc1+'\n'+ makeATable(alist,6,'background-color:cyan',['<input type="radio" id="toComponent_0" /> Main elements ','....'],0,' border="1" ')+'</div>'; 

      oink=atoc+E2_xmlToString2(tmp2a,1,0,sarg1,sarg2a,'0',['*','toComponent_'],'0',0) ; 

      var funcs=window.displayDiv+'\n'+window.strip+'\n'+window.getAttributes+'\n'+window.getWord+fset+'\n'+window.setFocusNow ;
      funcs='\n<script type="text/javascript">'+funcs+'\n</script> \n ';
      var goo='<html><head><title>Display of '+adesc+'</title>'+funcs+'</head><body>';
      oink=goo+oink+'\n</body></html>';

   } else {                                     // string passed

    stuff2=stuff2a.replace(/\&/g,'&amp;');
    stuff2=stuff2.replace(/\>/g,'&gt;');
    stuff2=stuff2.replace(/\</g,'&lt;');
    stuff2=stuff2.replace(/\n/g,'<br>');
    oink=ss+stuff2;
   }
   displayInWindow(oink,adesc1) ;
}

if (doexpand==0) {             // string sent -- convert html characters for display (NOTE: use stuff2a for textbox display
    stuff2=stuff2a.replace(/\&/g,'&amp;');
    stuff2=stuff2.replace(/\>/g,'&gt;');
    stuff2=stuff2.replace(/\</g,'&lt;');
    stuff2=stuff2.replace(/\n/g,'<br>');
}

stuff2=ss+stuff2;

if (useRightDiv==1 && stuff2a!==0) {                                 // ========= RIGHT DIV
  tmp=E2_xmlToString2(stuff2a,1,0,sarg1,sarg2,otherInfo,expDivs,spanDivs,checkUse) ; 
  write_moveBox(1,adesc,tmp); open_moveBox(1);
}


if (useLeftDiv==1 && stuff2a!==0) {                             // ========= LEFT DIV
  oof=E2_xmlToString2(stuff2a,1,0,sarg1,sarg2,otherInfo,expDivs,spanDivs,checkUse);
  write_moveBox(0,adesc,oof); open_moveBox(0);
}

// display in textbox
if (useTextBox==1) {                            // ========= TEXTBOX
  nodeToEdit=stuff2a ;
  iframeE=document.getElementById('editableBox');
  if (iframeE) {
    if (stuff2a===0) {
        stuff2='';
        toggleDisplay("backupNameSpan",1,'none');
    } else if  (doexpand==0) {
              stuff2=stuff2a+'\n ';                  // use stuff2 as is
    } else {
      toggleDisplay("backupNameSpan",1,'inline');
      toggleDisplay("askPreview",1,'inline');

      tmp=E2_getNodes(stuff2a,'lastModified');
      removeNodes(tmp);
      stuff2=E2_xmlToString(stuff2a,1) ;
      tmp='';
      tmp1=stuff2.split('\n');
      wascrlf=0;
      for (var m=0;m<tmp1.length;m++) {
         aline=tmp1[m];
         iscrlf=0;
         if (strip(aline)=='') iscrlf=1;
         if (iscrlf==1) {
           if (wascrlf>1) continue ;
           wascrlf++;
           aline='';
         } else {
           wascrlf=0;
         }
         tmp=tmp+aline+'\n';
      }
      stuff2=tmp;
    }                                   // node to expand, or string?

    iframeE.value=stuff2;               // and write to the textbox!

    displayDiv('showTextBoxId0',1)
    i2=document.getElementById('showTextBoxDesc');
    i2.title=adesc+'arf';
    i2.innerHTML=adesc1;
  

    if (enableTextSave==1) {
      toggleDisplay('showTextBoxDoSave',1,'inline');
      toggleDisplay("backupNameSpan",1,'inline');
      toggleDisplay("askPreview",1,'inline');
    } else {
      toggleDisplay('showTextBoxDoSave',1,'none');
      toggleDisplay("backupNameSpan",1,'none');
      toggleDisplay("askPreview",1,'none');
    }

  }
}


// jump to a element in this
return 1;
}

//======
// function sent to newWindow
function setFocusNow(cc,athis)   { 
   var dd="toComponent_"+strip(cc) ; 
   var ii=document.getElementById(dd);
   
   if (!ii || ii==null) return 1;

   ii.focus() ; 
      if (cc==0) {
        var ii2=athis.nextSibling;
        if (ii2 && ii2!==null) ii2.style.border='';
      } else {
        var ii2=ii.nextSibling;
       if (ii2 && ii2!==null) ii2.style.border='3px solid lime';
      }

 return 1 ;
}

//======================
// show contents of a sub (uses subList
function showStuffSub(aname,adesc,ageneric) {
var ii,i2;
var stuff2 ;
if (arguments.length<3) ageneric='';
if (arguments.length<2) {
    adesc="Description of: " +aname ;
}

 var taname=strip(aname).toUpperCase();

if (typeof(subList[taname])=='undefined') {
  alert('Error: no such <SUB> (set) = ' +aname);
  return 1;
}

showSomeStuff('',subList[taname],adesc,2,'',ageneric);


return 1;
}


//======================
// show contents of a include (uses includeNa
function editStuffIncludes(m,adesc) {
var ii,i2;
var stuff2,aname ;

if (typeof(includeFiles[m])=='undefined') {
  alert('Error: no such <INCLUDE> = ' +m);
  return 1;
}

aname=includeFiles[m];

if (arguments.length<2) {
    adesc="Description of INCLUDE: " +aname ;
}

xmlToSave='controlCompInclude '+m+' '+aname ;

showSomeStuff('',includeFilesContent[m],adesc,'1 YESTEXT NOLEFT NORIGHT NOWINDOW');


return 1;
}




//======================
// edit contents of a do (uses doList

function editStuffDo(jth,aname,ado,ado2,adesc) {
var stuff2 ;
var ii,i2,zoob;
if (arguments.length<3) ado='DO';
if (arguments.length<4) ado2='';
if (arguments.length<5) adesc='Description of '+ado+' '+aname+' ('+ado2+')'  ;
if (jth>-1 && typeof(doList[jth])=='undefined') {
  alert('Error: no such <'+ado+'> = ' +adesc);
  return 1;
}


 if (jth<0) {                           // a new  thing
    newName=strip(prompt('Please enter a name for this new DO',''));
    zoob=newName.indexOf(' ');
    if (zoob<0)    zoob=newName.indexOf(',');
    if (zoob<0)    zoob=newName.indexOf('"');
    if (zoob<0)    zoob=newName.indexOf("'");
    if (zoob>-1) {
        alert(' You must enter a single word name (no commas, quotes, or spaces)');
        return 1;
    }
    if (newName=='') {
        alert('Error: you MUST provide a name for this new '+aname);
        return 1;
    }
    newDesc=prompt('Please enter a description for '+newName,'created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    xmlToSave='controlComp DO 0' ;
    showSomeStuff('<!-- (new '+aname+') '+newName+' -->','',['(new '+aname+') '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
    location.hash="textBoxHash";

} else {

   xmlToSave='controlComp DO '+aname ;
   showSomeStuff('',doList[jth],adesc,'1 YESTEXT NOLEFT NORIGHT NOWINDOW');
   location.hash="textBoxHash";

}
return 1;
}



// =================================
// edit contents of a form (uses formList
function editStuffForm(jth,aname) {
var ii,i2,ss,gotForms,gotTasks,adesc;
var stuff2,mm,returnto ;

 adesc='Description of FORM: '+aname  ;


if (jth>-1 && typeof(formList[jth])=='undefined') {
  alert('Error: no such <FORM> = ' +adesc);
  return 1;
}

 if (jth<0) {                           // a new  thing
    newName=strip(prompt('Please enter a name for this new FORM',''));
    zoob=newName.indexOf(' ');
    if (zoob<0)    zoob=newName.indexOf(',');
    if (zoob<0)    zoob=newName.indexOf('"');
    if (zoob<0)    zoob=newName.indexOf("'");
    if (zoob>-1) {
        alert(' You must enter a single word name (no commas, quotes, or spaces)');
        return 1;
    }
    if (newName=='') {
        alert('Error: you MUST provide a name for this new '+aname);
        return 1;
    }
    newDesc=prompt('Please enter a description for '+newName,'created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    xmlToSave='controlComp FORM 0' ;
    newNoVuTasks=confirm('Hide the tasks table when displaying this form? \n (If you select Okay, remember to specify a vuTasksTable in a Submit or a Quit in this form)');
    showSomeStuff('<!-- (new '+aname+') '+newName+' -->','',['(new '+aname+') '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
    location.hash="textBoxHash";

} else {

  xmlToSave='controlComp FORM '+aname ;
  showSomeStuff('',formList[jth],adesc,'1 YESTEXT NOLEFT NORIGHT NOWINDOW');
   location.hash="textBoxHash";

}


return 1;
}


//======================
// show contents of a sub (uses subList
function editStuffSub(aname,adesc) {
var ii,i2;
var stuff2 ;
if (arguments.length<2) {
    adesc="Description of SUB: " +aname ;
}
xmlToSave='controlComp SUB '+aname ;

var  taname=strip(aname).toUpperCase();

 if (aname<0) {                           // a new  thing
    newName=strip(prompt('Please enter a name for this new SUB',''));
    zoob=newName.indexOf(' ');
    if (zoob<0)    zoob=newName.indexOf(',');
    if (zoob<0)    zoob=newName.indexOf('"');
    if (zoob<0)    zoob=newName.indexOf("'");
    if (zoob>-1) {
        alert(' You must enter a single word name (no commas, quotes, or spaces)');
        return 1;
    }
    if (newName=='') {
        alert('Error: you MUST provide a name for this new SUB');
        return 1;
    }
    newDesc=prompt('Please enter a description for '+newName,'created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    xmlToSave='controlComp SUB 0';
    showSomeStuff('<!-- (new SUB) '+newName+' -->','',['(new SUB) '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
   location.hash="textBoxHash";

  } else {              // edit existing

     var  taname=strip(aname).toUpperCase();
     if (typeof(subList[taname])=='undefined') {
          alert('Error: no such <SUB> = ' +aname);
         return 1;
      }
      showSomeStuff('',subList[taname],adesc,'1 YESTEXT NOLEFT NORIGHT NOWINDOW');
     location.hash="textBoxHash";
 }
return 1;
}


// =================================
// edit contents of a sub (uses subListCustom
function xeditStuffSubControl(jth,aname) {
var ii,i2,ss,gotForms,gotTasks,adesc;
var stuff2,mm,returnto ;

 adesc='Description of SUB: '+aname  ;


if (jth>-1 && typeof(subListContro[jth])=='undefined') {
  alert('Error: no such <SUB> = ' +adesc);
  return 1;
}

 if (jth<0) {                           // a new  thing
    newName=strip(prompt('Please enter a name for this new SUB',''));
    zoob=newName.indexOf(' ');
    if (zoob<0)    zoob=newName.indexOf(',');
    if (zoob<0)    zoob=newName.indexOf('"');
    if (zoob<0)    zoob=newName.indexOf("'");
    if (zoob>-1) {
        alert(' You must enter a single word name (no commas, quotes, or spaces)');
        return 1;
    }
    if (newName=='') {
        alert('Error: you MUST provide a name for this new '+aname);
        return 1;
    }
    newDesc=prompt('Please enter a description for '+newName,'created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    xmlToSave='controlComp FORM 0' ;
    showSomeStuff('<!-- (new '+aname+') '+newName+' -->','',['(new '+aname+') '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
} else {

  xmlToSave='controlComp SUB '+aname ;
  showSomeStuff('',formList[jth],adesc,'1 YESTEXT NOLEFT NORIGHT NOWINDOW');
}


return 1;
}





//======================
// show contents of a PANEL(uses subList
function editStuffPanel(aname,adesc) {
var ii,i2;
var stuff2 ;
if (arguments.length<2) {
    adesc="Description of PANEL component: " +aname ;
}

xmlToSave='controlComp SUB '+aname ;
if (typeof(subList[aname])=='undefined') {
  alert('Error: no such <PANEL> component = ' +aname);
  return 1;
}
showSomeStuff('',subList[aname],adesc,'1 YESTEXT NOLEFT NORIGHT NOWINDOW');
location.hash="textBoxHash";


return 1;

}


//======================
// show contents of a sub (uses subList
function editStuffAttributes(aname,adesc) {
var ii,i2;
var stuff2 ;
if (arguments.length<2) {
    adesc="Attributes: " +aname ;
}

xmlToSave='controlComp SUB '+aname ;
if (typeof(subList[aname])=='undefined') {
  alert('Error: no such <ATTRIBUTES> = ' +aname);
  return 1;
}
showSomeStuff('',subList[aname],adesc,'1 YESTEXT NOLEFT NORIGHT NOWINDOW');


return 1;

}


//======================
// show a level 1 componenbt of a spec file (by number)
// example: xmlToSave='specComponent  -1 SUB ' ; showSpecComponent(-1,'SUB','(New SUB) ');

function showSpecComponent(ith,aname,adesc) {
 var zoob;
 if (ith<0) {                           // a new  thing
    newName=strip(prompt('Please enter a name for this new '+aname,''));
    zoob=newName.indexOf(' ');
    if (zoob<0)    zoob=newName.indexOf(',');
    if (zoob<0)    zoob=newName.indexOf('"');
    if (zoob<0)    zoob=newName.indexOf("'");
    if (zoob>-1) {
        alert(' You must enter a single word name (no commas, quotes, or spaces)');
        return 1;
    }
    if (newName=='') {
        alert('Error: you MUST provide a name for this new '+aname);
        return 1;
    }
    newDesc=prompt('Please enter a description for '+newName,'created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    showSomeStuff('<!-- (new '+aname+') '+newName+' -->','',['(new '+aname+') '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
 } else {   
   zoob=origSpecNode.childNodes ;
   showSomeStuff('',zoob[ith],[aname,adesc],1+' YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
 }
 location.hash="textBoxHash";

}

// show a level 1 use component of a specElements file (by number)
function showSpecUse(ith,aname,adesc) {
 var zoob;

 if (ith<0) {                           // a new  thing
    newName=strip(prompt('Please enter a name for this new '+aname,''));
    zoob=newName.indexOf(' ');
    if (zoob<0)    zoob=newName.indexOf(',');
    if (zoob<0)    zoob=newName.indexOf('"');
    if (zoob<0)    zoob=newName.indexOf("'");
    if (zoob>-1) {
        alert(' You must enter a single word name (no commas, quotes, or spaces)');
        return 1;
    }
    if (newName=='') {
        alert('Error: you MUST provide a name for this new '+aname);
        return 1;
    }
    newDesc=prompt('Please enter a description for '+newName,'created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    showSomeStuff('<!-- (new '+aname+') '+newName+' -->','',['(new '+aname+') '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;

 } else {   

//   zoob=origSpecNode.childNodes ;
//   showSomeStuff('',zoob[ith],[aname,adesc],1+' YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
     zoob=E2_getNodes(specElementsFile,'use');
     if (zoob.length==0) return 0;
     zoob=zoob[0].childNodes ;
     showSomeStuff('',zoob[ith],[aname,adesc],1+' YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
  }
  location.hash="textBoxHash";
  return 1;
}

// show a level 1 call component of a specElements file (by number)
function showSpecCall(ith,aname,adesc) {

 var zoob,zoob0,m,tmp;

 if (ith<0) {                           // a new  thing
    aname=prompt('Enter a comma delimited list of sections or section.groups that will use this call (* to use in all sections and groups ','*');
    if (aname=='') {
        alert('Error: you MUST provide a list of sections or section.groups ');
        return 1;
    }
    newName=aname.replace(/\s/g,'');
    newDesc=prompt('Please enter a description  ','created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    showSomeStuff('<!-- (CALL for) '+newName+' -->','',['(CALL for) '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;

 } else {   
   zoob0=E2_getNodes(specElementsFile,'calls');
   if (zoob0.length==0) return 0;
   zoob=zoob0[0].childNodes ;
   showSomeStuff('',zoob[ith],[aname,adesc],1+' YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
 }
 location.hash="textBoxHash";
  return 1;
}

//======================
// show a single module in text box
function editModule(m,im,aname,adesc) {

 var afile,zoob,a1;
//  afile=moduleFiles[m];

 if (im<0) {                           // a new  thing
    newName=strip(prompt('Please enter a name for this new '+aname,''));
    zoob=newName.indexOf(' ');
    if (zoob<0)    zoob=newName.indexOf(',');
    if (zoob<0)    zoob=newName.indexOf('"');
    if (zoob<0)    zoob=newName.indexOf("'");
    if (zoob>-1) {
        alert(' You must enter a single word name (no commas, quotes, or spaces)');
        return 1;
    }
    if (newName=='') {
        alert('Error: you MUST provide a name for this new '+aname);
        return 1;
    }
    newDesc=prompt('Please enter a description for '+newName,'created '+ svy_currentTime(2,2));
    newDesc=newDesc.replace(/\"/g,'`');  
    showSomeStuff('<!-- (new '+aname+') '+newName+' -->','',['(new '+aname+') '+newName,newDesc],'0 YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
 } else {   
    zoob=moduleFilesContent[m].childNodes ;
    a1=E2_xmlToDomCmt(zoob[im]);              // make a copy (stuff might be removed)
    showSomeStuff('',a1,[aname,adesc],1+' YESTEXT  NOWINDOW NOLEFT NORIGHT ') ;
 }
 location.hash="textBoxHash";
 return 1 ;

}

//======================
// show contents of a sub (uses subList
function showStuffAttributes(aname,adesc) {
var ii,i2;
var stuff2 ;

if (arguments.length<2) adesc="Description of: " +aname ;


if (typeof(subList[aname])=='undefined') {
  alert('Error: no such <SUB> (attributes) = ' +aname);
  return 1;
}

showSomeStuff('',subList[aname],adesc,1);
location.hash="textBoxHash";

return 1;
}

//======================
// show contents of a sub (uses subList
function showStuffDisplay(jj,aname,adesc) {
var ii,i2;
var stuff2 ;
var vv,tname ;
var gotForms=[], gotTasks=[],mm;

if (arguments.length<3) adesc="Description of: " +aname ;

if (typeof(subList[aname])=='undefined') {
  alert('Error: no such <SUB> (display) = ' +aname);
  return 1;
}


vv=subList[aname].getElementsByTagName('*');
gotForms=[]; gotTasks=[];
for (var mm=0;mm<vv.length;mm++) {
 aa=getAttributes(vv[mm],'doform','');
 if (aa!=='') gotForms=gotForms.concat(aa);
 aa=getAttributes(vv[mm],'do dotask dotasks','');
 if (aa!=='') gotTasks=gotTasks.concat(aa);
}
ss='<div class="displayForms"><table>';

ss=ss+'<tr><th>'+gotForms.length+' forms referenced:</th><td>'
for (var mm=0;mm<gotForms.length;mm++) {
  tname=strip(gotForms[mm]).toUpperCase();
  if (typeof(formListRef[tname])=='undefined') {
        alert('Error: non-existent FORM = '+tname);
        return 1;
  }
  ss=ss+' ' +formListRef[tname];
}
ss=ss+'</td></tr> '


ss=ss+'<tr><th>'+gotTasks.length+' tasks referenced:</th><td>'
for (var mm=0;mm<gotTasks.length;mm++) {
  tname=strip(gotTasks[mm]).toUpperCase();
  if (typeof(doListRef[tname])=='undefined') {
        alert('Error: non-existent DO = '+tname);
        return 1;
  }
  ss=ss+' ' +doListRef[tname];
}
ss=ss+'</td></tr> '


ss=ss+'</table></div> \n \n ';

var igoo=document.getElementById('displayOthers'+jj);
if (igoo) igoo.innerHTML=ss;

showSomeStuff(ss,subList[aname],adesc,1);
location.hash="textBoxHash";

return 1;
}


//======================
// show contents of a do (uses doList

function showStuffDo(jth,aname,ado,ado2,adesc) {
var stuff2 ;
var ii,i2;
if (arguments.length<3) ado='DO';
if (arguments.length<4) ado2='';
if (arguments.length<5) adesc='Description of '+ado+' '+aname+' ('+ado2+')'  ;

if (typeof(doList[jth])=='undefined') {
  alert('Error: no such <'+ado+'> = ' +adesc);
  return 1;
}

showSomeStuff('',doList[jth],adesc,1,ado2);

return 1;
}

//======================
// show contents of a section (uses doList

function showStuffSection(jth,aname,adesc) {
var stuff2,astuff ;
var ii,i2,taname,afunc;
var inplist,mn,ithnode,afunc,adesc2,adescs;
var grplist='';

taname=strip(aname).toUpperCase();

if (adesc=='') {
   adesc='Description of: '+aname ;
} else {
 adesc='Section: '+aname+'<br/>'+adesc;
}
if (typeof(doList[jth])=='undefined') {
  alert('Error: no such Section = ' +adesc);
  return 1;
}

//  adesc=adesc+'<br/>'+sectionToGroups[taname]+'<br/>';

adescs=[];
adescs[0]=adesc;
adescs[1]='';

if (typeof(sectionToGroups[taname])!=='undefined') {
  adescs[1]='<br/>'+sectionToGroups[taname]+'<br/>';
}

if (typeof(callList[taname])!=='undefined') {
  astuff='<div style="margin:1px 10px 1px 10px"><table><tr><th>'+callList[aname].length+' calls</th>';
  inplist='';
  for (mn=0;mn<callList[aname].length;mn++) {
        ithnode=callList[aname][mn] ;
        adesc2=getAttributes(callListNodes[ithnode],'desc summary message','#'+mn);
        afunc=makeFuncCall('showACall',aname,ithnode,adesc2); 
        inplist=inplist+' <input type="button" title="'+adesc2+'" value="'+(mn+1)+'" onClick="'+afunc+'" /> ';
  }
  astuff=astuff+'<td>'+inplist+'</td></tr></table></div> ';
  adescs[0]=adescs[0]+astuff ;
}
showSomeStuff('',doList[jth],adescs,1);

return 1;
}



//======================
// show  a call
function showACall(aname,mth,adesc) {
anode=callListNodes[mth];
adesc='Call for  '+aname+'<br/>'+adesc;

showSomeStuff('',anode,adesc,1);
return 1 ;

}


//======================
// show contents of a grpup (uses groupList

function showStuffGroup(asec,aname,adesc){

var astuff,mn,inplist,ithnode,adesc2,afunc,taname ;

taname=strip(aname).toUpperCase() ;
tasec=strip(asec).toUpperCase();

if (arguments.length<3) adesc='Description of Section and Group: '+ aname ;

if (typeof(groupList[aname])=='undefined') {
  alert('Error: no such Group = ' +adesc);
  return 1;
}

inplist='';


if (typeof(callList['*'])!=='undefined') {
  for (mn=0;mn<callList['*'].length;mn++) {
        ithnode=callList['*'][mn] ;
        adesc2=getAttributes(callListNodes[ithnode],'desc summary message','#'+mn);
        afunc=makeFuncCall('showACall',asec,ithnode,adesc2); 
        inplist=inplist+' <input type="button" title="'+adesc2+'" value="*: '+(mn+1)+'" onClick="'+afunc+'" /> ';
  }
}

if (typeof(callList[tasec])!=='undefined') {
  for (mn=0;mn<callList[tasec].length;mn++) {
        ithnode=callList[tasec][mn] ;
        adesc2=getAttributes(callListNodes[ithnode],'desc summary message','#'+mn);
        afunc=makeFuncCall('showACall',asec,ithnode,adesc2); 
        inplist=inplist+' <input type="button" title="'+adesc2+'" value="Section: '+(mn+1)+'" onClick="'+afunc+'" /> ';
  }
}

if (typeof(callList[taname])!=='undefined') {
  for (mn=0;mn<callList[taname].length;mn++) {
        ithnode=callList[taname][mn] ;
        adesc2=getAttributes(callListNodes[ithnode],'desc summary message','#'+(1+mn));
        afunc=makeFuncCall('showACall',aname,ithnode,adesc2);
        inplist=inplist+' <input type="button" title="'+adesc2+'" value="Group: '+(mn+1)+'" onClick="'+afunc+'" /> ';
  }
}


if (inplist!=='') {
  astuff='<div style="margin:1px 10px 1px 10px"><table><tr><th>'+'Section and group &lt;CALL&gt;: </th>';
  astuff=astuff+'<td>'+inplist+'</td></tr></table></div> ';
  adesc=adesc+astuff ;
}



showSomeStuff('',groupList[aname],adesc,1);

return 1;
}



//======================
// show contents of a do (uses doList
function showStuffIncludes(jth,aname,nolist) {
var ii,i2,tmp;
if (arguments.length<3) nolist='';
var stuff2,adesc,stuff2a ;

if (jth<0) { 
   adesc='Create an INCLUDE file, using  ';
   i2=document.getElementById("newIncludeName");
   i2val=strip(i2.value) ;

   if (i2val=='') {
        alert('You forgot to enter a name for the new <INCLUDE> file.');
        return 0;
   }
   if (getWord(i2val).length>1) {
        alert('Sorry, you must use a one-word name ');
        return 0;
   }
   if (i2val=='0' || i2val=='1') {
        alert('Sorry, "0" and "1" are illegal names ');
        return 0;
   }
   i2Val=strip(i2val);
   adesc='Create a new INCLUDE file= '+ i2val  ;
   if (i2val.toUpperCase().indexOf('.XML')<0) i2val=i2Val+'.xml';
   newIncludeName=getInstXML+workingInstrument+'/specs/'+i2val ;


   showSomeStuff('',0,adesc,1+' '+nolist); 
  location.hash="textBoxHash";

} else {

  adesc='The INCLUDE file: '+aname  ;
  if (typeof(includeFilesContent[jth])=='undefined') {
     alert('Error: no such <INCLUDE> = ' +adesc);
     return 1;
  }
  showSomeStuff('',includeFilesContent[jth],adesc,1+' '+nolist); 
 location.hash="textBoxHash";

}




return 1;
}

//======================
// show contents of a do (uses doList
function showSpecElements(mm,nolist) {
var ii,i2,divExp='',spanExp='';
if (arguments.length<2) nolist=' ';
var stuff2,adesc,stuff2a ;
adesc='The spec_elements file: '  ;

showSomeStuff('',specElementsFile,adesc,1+' '+nolist,'','',7,['font-weight:700;font-size:120%;border:1px solid blue;margin:15px 0px 5px 0px','color:blue;font-weight:500;font-size:90%','font-weight:400;color:black;font-size:90%'],divExp,spanExp); 
 location.hash="textBoxHash";

return 1;
}


// =================================
// show contents of a form (uses formList
function showStuffForm(jth,aname) {
var ii,i2,ss,gotForms,gotTasks,adesc;
var stuff2,returnto ;
var newGot,gotRef,mm,tname;

 adesc='Description of FORM: '+aname  ;


if (typeof(formList[jth])=='undefined') {
  alert('Error: no such <FORM> = ' +adesc);
  return 1;
}

vv=formList[jth].getElementsByTagName('*');
gotForms=[]; gotTasks=[];
for (var mm=0;mm<vv.length;mm++) {
 aa=getAttributes(vv[mm],'doform','');
 if (aa!=='') gotForms=gotForms.concat(aa);
 aa=getAttributes(vv[mm],'do dotask dotasks','');
 if (aa!=='') gotTasks=gotTasks.concat(aa);
}
ss='<div class="displayForms"><table>';

ss=ss+'<tr><th>'+gotForms.length+' forms referenced:</th><td>'
for (var mm=0;mm<gotForms.length;mm++) {
  tname=strip(gotForms[mm]).toUpperCase();
  if (typeof(formListRef[tname])=='undefined') {
        alert('Error: non-existent FORM = '+tname);
        return 1;
  }
  ss=ss+' ' +formListRef[tname];
}
ss=ss+'</td></tr> '


// remove duplicate tasks

newGot=[]; gotRef={};
for (var mm=0;mm<gotTasks.length;mm++) {
  tname=strip(gotTasks[mm]).toUpperCase();
  if (typeof(gotRef[tname])=='undefined') {
        gotRef[tname]=1;
        newGot=newGot.concat(gotTasks[mm]);
   }
}
ss=ss+'<tr><th>'+newGot.length+' tasks referenced:</th><td>'
for (var mm=0;mm<newGot.length;mm++) {
  tname=strip(newGot[mm]).toUpperCase();
  if (typeof(doListRef[tname])=='undefined') {
        alert('Error: non-existent DO = '+tname);
        return 1;
  }
  ss=ss+' ' +doListRef[tname];
}
ss=ss+'</td></tr> '
ss=ss+'</table></div> \n \n ';


showSomeStuff(ss,formList[jth],adesc,1);
location.hash="textBoxHash";


var igoo=document.getElementById('displayFormOthers'+jth);
if (igoo) igoo.innerHTML=ss;


return 1;
}


//========
// display control  file
function  showControlFile(j,ii){
stuff2=controlNode;
var old1=enableTextSave ;
if (arguments.length>1) enableTextSave=0;
showSomeStuff('',stuff2,'The full control panel program file ',j) ;
location.hash="textBoxHash";
enableTextSave=old1 ;
return 1;
}

//========
// display control  file
function  showSpecFile(nolist,aedit){
var a1 ;
if (arguments.length<1) nolist='';
if (arguments.length<2) aedit=0;

if (aedit==1) {
  a1=E2_xmlToDomCmt(origSpecNode);              // make a copy (stuff might be removed)
  showSomeStuff('',a1,'The full SPEC file ... ',2+' '+nolist) ;
} else {
  showSomeStuff('',origSpecNode,'The full SPEC file ',2+' '+nolist) ;
}
 location.hash="textBoxHash";

return 1;
}



//========
// display an include file
function  showInclude(j0){
var stuff2,aname,j;
j=j0;
if (isNaN(j)) {                  // string, seach for match 
  aname=strip(j0).toUpperCase();
  j=-1;
  for (var m=0;m<includeFiles.length;m++) {
      if (aname==includeFiles[m]) { 
          j=m;
          break;
     }
  }
  if (j<0) {
        alert('Unable to find include File= '+j0);
        return 0;
 }

}
stuff2=includeFilesContent[j];

showSomeStuff('',stuff2,'Include file= '+includeFiles[j],1) ;
location.hash="textBoxHash";
return 1;
}

//====================================== END of control panel program functions 

//===================
// make a function with argument list (arguments are all strings 
function makeFuncCall(fname,arg1,arg2,arg3,arg4,arg5,arg6,arg7) {
var stuff,a1,m,anarg;

stuff=fname+'(' ;
for (var m=1;m<arguments.length;m++) {
  anarg=arguments[m];
  if (typeof(anarg)=='string') anarg=anarg.replace(/\'/g,'`'); 
  a1="'"+anarg+"'";
  if (m<arguments.length-1) {
        stuff=stuff+a1+',';
  } else {
        stuff=stuff+a1+')';
  }
}

return stuff;
}

// ========
// Expand an xml node into a string, with spacing
// this is highly recursive!
//
// anode: node to expand
// opt1: if 1, do NOT include mother node (just expand children)
// ilevel: indentation level. 
// padLength: integer: # of  pixels to use when padding. 10 (pixels)if not specified
// levelStyles: array. each element is additional style for a level (if level>levelStyles.length, no additional style for that level)
// otherinfo: optional. Used to instruct how to display text (_addText uses otherinfo). 
// expDivs: string, or 2 element array.
//          string, or first element: list of elements that can be expanded. Default, or '*' is all elements
//          2nd element, if specified: name to use in a <a name="anameMth"> link (placed before first level elements)
// spanDivs: list of elements to be displayed in a <span> (and that will have a </span> displayed. Default is none
// checkUse: if 1, then add <use> stuff
// special case: otherInfo='0' and spanDivs='*' : used to display full xml in new window



function E2_xmlToString2(anode,opt1,ilevel,padLength,levelStyles,otherInfo,expDivs0,spanDivs,checkUse) {
var dname,daspace,aname,stuff,itype,ii,atext,astuff,atts,taname; 
var atts,i0,attvalue,attname,astyle,gname,dname2,isInc,theNameLink;
var grpname,addText,eetype,anameAtts,eetype2,daspace2,padSpace,nthElem=0,tmp,addcrlfs;
var isblue='',spdiv ;
var expDivs,nameBase,parname;

if (typeof(anode)!=='object') return '';
if (arguments.length<2) opt1=0;
if (arguments.length<3) ilevel=0 ;
if (arguments.length<4) padLength=20;  
if (arguments.length<5) levelStyles=[];
if (arguments.length<6) otherInfo='';
if (arguments.length<7)  expDivs0='';
if (arguments.length<8) {
   spanDivs=';aa+0;';
} else {  
  spanDivs=' '+strip(spanDivs).toUpperCase()+' ';
}

if (arguments.length<9)checkUse=0;


if (typeof(expDivs0)=='object') {
  expDivs=expDivs0[0];
  nameBase=expDivs0[1]
} else {
  nameBase='';
  expDivs=expDivs0 ;
}
expDivs=strip(expDivs).toUpperCase();

if (ilevel<0) {
  alert('ilevel < 0 not supported ');
  return 0;
}

dname=' '+Math.random(); dname='_'+dname.substr(3);
daspace=((padLength*ilevel)+1)+'px ';
padSpace='';
if (otherInfo=='0') {
  for (ii=0;ii<ilevel;ii++) {
    padSpace=padSpace+'&nbsp;&nbsp;';
  }
}

stuff='';

if (opt1==0) {                                  // start with this node
  aname=strip(anode.nodeName).toUpperCase() ;
  atts='';
  if (anode.attributes)  atts=E2_xmlToString2_atts(anode,checkUse);
  astyle=E2_xmlToString2_style(ilevel,levelStyles);
  stuff='<div id="'+dname+'" style="margin-left:'+daspace+';'+astyle+'"><span style="font-size:120%"> &lt;'+aname+' '+atts+'&gt; </span> \n ';
  ilevel=ilevel+1;
}

for (ii=0;ii<anode.childNodes.length;ii++) {
  itype=anode.childNodes[ii].nodeType;
  if (itype==3 || itype==8) {
      if (itype==3) {                            // text
       atext=anode.childNodes[ii].nodeValue;
        if (strip(atext)==='') continue ;
        if (otherInfo=='') {
            parname=anode.childNodes[ii].parentNode.nodeName;
            addText=E2_xmlToString2_addText(parname,atext);
            stuff=stuff+'<span class="showXMLtext">'+addText+'</span>';  
        } else {
            addText=E2_xmlToString2_addText(otherInfo,atext);
            addText=addText.replace(/\n/g,'<br/>');
            stuff=stuff+'<span style="color:green">'+addText+'</span>';  
        }
     } else {                   // <!-- comment -->
        atext=anode.childNodes[ii].nodeValue;
        dname2=' '+Math.random(); dname2='_'+dname2.substr(3);
        gname='DO_'+dname2;
        spdiv='span ';
        if (atext.indexOf('\n')>-1) spdiv='div ';

        abutton='<'+spdiv+'style="border:1px dashed cyan"><input style="font-size:50%" type="button" value="<!-->"  title="view  comment" onClick="displayDiv(\''+gname+'\',\'TOGGLE\')" />';
        atext=atext.replace(/\&/g,'&amp;');
        atext=atext.replace(/\</g,'&lt;');
        atext=atext.replace(/\>/g,'&gt;');
        atext=atext.replace(/\n/g,'<br />');
        stuff=stuff+abutton+'<span id="'+gname+'" style="display:none;color:blue">'+atext+'</span></'+spdiv+'>';  
      }

  } else {

     theNameLink=''; addcrlfs='\n';
     if (nameBase!=='' && ilevel==0 ) {
         nthElem++ ;
         taname=getAttributes(anode.childNodes[ii],'name id file','');
            if (taname=='')taname=strip(ii);
            taname=strip(taname).toUpperCase();
         theNameLink='\n<input name="theFirstOnes" onClick="setFocusNow(0,this)" type="radio" id="'+nameBase+taname+'" title="Back to top" />' ;
         addcrlfs='\n';
     }
     
     tmp=ilevel+1;
     if (anode.childNodes[ii].childNodes.length>0) astuff=E2_xmlToString2(anode.childNodes[ii],1,tmp,padLength,levelStyles,otherInfo,expDivs,spanDivs,checkUse) ; 

     aname=strip(anode.childNodes[ii].nodeName).toUpperCase() ;

     dname2=' '+Math.random(); dname2='_'+dname2.substr(3);
     daspace=padLength*ilevel+'px ';

     astyle=E2_xmlToString2_style(ilevel,levelStyles);
     atts='';
     if (anode.childNodes[ii].attributes)  atts=E2_xmlToString2_atts(anode.childNodes[ii],checkUse);

    if (otherInfo!=='0' && (aname=='CMT' || aname=='COMMENT' || aname=='C') ) {
        anameAtts='<span style="color:blue">Comment: </span>';
     } else {
       if (aname=='CMT' || aname=='COMMENT' || aname=='C')  {
          anameAtts='<span style="color:blue">'+aname+'</span> '+atts ;
       } else {
          anameAtts=aname+' '+atts ;
       }
     }

    grpname=getAttributes(anode.childNodes[ii],'name','');
    if (anode.childNodes[ii].childNodes.length>0) {
       gname='DO_'+dname2;
       abutton=''; eetype='div'; eetype2='';

       if (spanDivs!=='') {                             // divs to treat as SPANS
          if (spanDivs.indexOf(aname)>-1 ) {
              eetype='span';
              eetype2='span';
              daspace='5px; ';
          }
          if (spanDivs.indexOf('*')>-1) {
              eetype='div';
              eetype2='div';
              daspace='5px; ';
          }

       }
       if (strip(expDivs)=='' || expDivs.indexOf(' '+aname+' ')>-1 ) {          // divs to "expand"
            eetype='div';
            abutton='<input type="checkbox" style="color:cyan;background-color:yellow;font-size:3px" checked  onClick="displayDiv(\''+gname+'\',\'TOGGLE\')" />';
       }

// from an INCLUDE?
       if (anode.childNodes[ii].attributes['fromIncludeFile'] || anode.childNodes[ii].attributes['fromIncludeSub'])  {
           if (anode.childNodes[ii] && anode.childNodes[ii].attributes['fromIncludeFile'])  {             // incldue fle
            astyle=astyle+';border-left:5px solid yellow;border-top:7px solid yellow;border-bottom:5px solid yellow;'; 
           } else {                                       // include sub
              astyle=astyle+';border-left:3px dotted yellow;border-top:5px dotted yellow;border-bottom:5px dotted yellow;'; 
           }
           stuff=stuff+addcrlfs+'<'+eetype+'  id="'+dname2+'" style="'+'margin-left:'+daspace+';'+astyle+'"> '+theNameLink+padSpace+abutton+'<span ><em>&lt;'+anameAtts+'&gt;</em></span> \n ';

        } else {                                // not from an INCLUDE

          stuff=stuff+addcrlfs+'<'+eetype+' id="'+dname2+'" style="'+'margin-left:'+daspace+';'+astyle+'"> '+theNameLink+padSpace+abutton+'<em>&lt;'+anameAtts+'&gt;</em> \n ';
        }

       stuff=stuff+'<span id="'+gname+'">'+astuff+'</span> ' ;
       if (anode.childNodes[ii].attributes['fromIncludeFile'])  {
            stuff=stuff+' <span ><em>&lt;/'+aname+'&gt;</em></span> \n ';
      }

      if (eetype2!='') {
          stuff=stuff+' <em>&lt;/'+aname+'&gt;</em> </'+eetype2+'> ';
      } else {
         stuff=stuff+' </div>';
      }

    } else {                    // no children

       daspace2='margin-left:'+daspace;
       if (otherInfo=='0') daspace2='';
       isblue=''; eetype='div';

       if (aname=='SHOW') {
         isblue=';color:darkblue;';
         eetype='span';
         padSpace=' '; daspace=' '; daspace2=' ';
       }
       if (anode.childNodes[ii].attributes && anode.childNodes[ii].attributes['fromIncludeFile'])  {
          stuff=stuff+addcrlfs+'<'+eetype+' id="'+dname2+'" style="'+isblue+daspace2+';'+astyle+'">'+theNameLink+padSpace+' <span style="background-color:yellow"><em>&lt;'+anameAtts+' /&gt;</em></span> </'+eetype+'> \n ';
        } else {
          stuff=stuff+addcrlfs+'<'+eetype+' id="'+dname2+'" style="'+isblue+daspace2+';'+astyle+'">'+theNameLink+padSpace+' <em> &lt;'+anameAtts+' /&gt;</em>  </'+eetype+'> \n ';
        }
    }                           // children?
        
  }                     // type=3

}                       // anode.childnodes.length

if (opt1==0) {
  stuff=stuff+'\n <\div> \n ';
}

return stuff;

    
//input
}



// =====
// depending on parentnode type, modify text to display
function E2_xmlToString2_addText(pname,datext) {
var tpname=strip(pname).toUpperCase();
var dd,amod,m,mods,tmp;

if (tpname=='CMT' || tpname=='COMMENT' || tpname=='C') {
   return '<span class="showComment">'+datext+'</span>' ;
}

if (tpname=='MODULES') {
  mods=getWord(datext);
  dd='';
  for (var m=0;m<mods.length;m++) {
    tmp=makeFuncCall('showAModule',mods[m]);
    aclick='onClick="'+tmp+'" ';
    amod='<input type="button" value="'+mods[m]+'" title="click to display this module" '+aclick+' > ';
    
    dd=dd+' '+amod;
  }
  return dd;
}

if (tpname=='MODULEFILES') {
  mods=getWord(datext);

  dd='';
  for (var m=0;m<mods.length;m++) {
    aclick=' onClick="'+makeFuncCall('showAModuleFile',mods[m])+'"' ;
    amod='<input type="button" value="'+mods[m]+'" title="click to display this module file" '+aclick+' > ';
    dd=dd+' '+amod;
  }

  return dd;
}

return datext;
}

// =====
// make st ylestring for e2_xmltoString2
function E2_xmlToString2_style(ilevel,levelStyles) {
var astyle;
  astyle='';
  if (ilevel<levelStyles.length) astyle=levelStyles[ilevel];
 return astyle;
}

// =====
// make attribute string for e2_xmltoString2
function E2_xmlToString2_atts(bnode,checkUse) {
var messes=' MESSAGE MESS TITLE DESC DESCRIPTION SUMMARY  ';
var atts,attname,attvalue,i0,tname,afunc;
atts='';
    for (i0=0;i0<bnode.attributes.length;i0++) {
      attname=bnode.attributes[i0].nodeName ; 
      attvalue=bnode.attributes[i0].nodeValue;
      if (attname.toUpperCase()=='USE' && checkUse==1 ) {
          afunc=makeFuncCall('showUse',attvalue);
          attname='<input onClick="'+afunc+'" type="button" value="USE" title="click to view the USE attributes for '+attvalue+'" style="color:blue" /> ' ;
      }
      tname=' '+strip(attname).toUpperCase()+' ';  
      attvalue=bnode.attributes[i0].nodeValue;
      if (messes.indexOf(tname)>-1) {
         atts=atts+' '+attname+'="<span style="font-style:normal;font-size:110%;font-family:serif">'+attvalue+'"</span> '; 
      } else {
         atts=atts+' '+attname+'="'+attvalue+'" ';
       }
    }
    if (atts!=='') atts='<span style="font-style:normal;font-family:monospace;font-style:">'+atts+'</span>';

 return atts;

}

// tname


//==========================
// display a module
function showAModule(amod) {
var divExp,spanExp,foundIn,stuff,stuff2,a1,a1s,iss,tamod,flist,asec ;
var tmp1={};

   amod=strip(amod).toUpperCase();
   divExp='DIV TABLE TR OL UL MENU IF THEN ELSE  HISTORY SET MODULE' ;
   spanExp='B EM U TT ';
   tamod=strip(amod).toUpperCase() ;
   stuff='';

   if (typeof(modulesToGroup[tamod])!=='undefined') {
         foundIn=modulesToGroup[tamod];    
         flist=getWord(foundIn,0,',');
         for (var iss=0;iss<flist.length;iss++) {
              a1=strip(flist[iss]);
              a1s=getWord(a1,0,'.') ;
              asec=strip(a1s[0]).toUpperCase() ;
              if (typeof(tmp1[asec])=='undefined') tmp1[asec]='';
              if (tmp1[asec]!=='') tmp1[asec]=tmp1[asec]+', ';
              tmp1[asec]=tmp1[asec]+a1s[1];
        }                      

         stuff='<tabe><tr><td><span style="font-size:90%"> Found in: </span></td><td>';
         stuff2='<table cellpadding="5" rules="rows"><tr><th>section</th><td>groups</td></tr>';
         for (var iss in tmp1) {
              a1=tmp1[iss] ;
              stuff2=stuff2+'<tr><td><b>'+iss+'</b></td><td>'+a1+'</td></tr>';
         }
         stuff=stuff+stuff2+"</table></td></tr></table>" ;
   }
   showSomeStuff('',moduleList[amod],'Module : '+amod+stuff,2,'','',7,'',divExp,spanExp,1);
 location.hash="textBoxHash";

   return  1; 
}

//================================
// display a <USE> spec
function showUse(ause) {
ause=strip(ause).toUpperCase() ;
if (typeof(useList[ause])=='undefined') { 
  alert(' No USE defined for: '+ause); 
  return 1 ;
}
 showSomeStuff('',useList[ause],'USE component '+ause+':',1); 
return 1;
}

//================================
// display a module file
function showAModuleFile(afile,nolist) {
if (arguments.length<2) nolist=' ' ;
var tafile,m,divExp,spanExp,cfile,atmp;
var a1;
tafile=strip(afile).toUpperCase();
for (var m=0;m<moduleFiles.length;m++) {
  cfile=strip(moduleFiles[m]).toUpperCase() ;  
  if (tafile==cfile) {                     // retrieve the module file
   divExp='DIV TABLE TR OL UL MENU IF THEN ELSE  HISTORY SET MODULE' ;
   spanExp='B EM U TT ';
   atmp=1+' '+nolist;
   a1=E2_xmlToDomCmt(moduleFilesContent[m]);              // make a copy (stuff might be removed)
   showSomeStuff('',a1,'Module file: '+afile,atmp,'','',7,['font-weight:700;margin:15px 0px 5px 0px','font-weight:400'],divExp,spanExp);
   location.hash="textBoxHash";
   return  1; 
  }
}
location.hash="textBoxHash";

return 1;
}



