//
// ******************************************************************************************************
// *                                                                                                    *
// *                                  Javascript Classes and Functions                                  *
// *                                                                                                    *
// *  Class                                           Base Class                                        *
// *                                                                                                    *
// *    ShowPage_Edit                                   (n/a)                                           *
// *    ShowPage_TextEdit                               (n/a)                                           *
// *                                                                                                    *
// ******************************************************************************************************
//

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class ShowPage_Edit                                                                                *
// *                                                                                                    *
// *   Generic text block to be edited (plain text, HTML, XML or any variant thereof)                   *
// *                                                                                                    *
// ******************************************************************************************************
//
// constructor
//
function ShowPage_Edit(section, block) {
  if (arguments.length == 0 || section === null) {
  } else if (typeof section != "object") {
    this.init.apply(this, arguments);
  } else if (section instanceof ShowPage_Edit) {
    this.init(section.section, section.block);
  } else /* if (section instanceof Array) */ {
    this.init(section["section"], section["block"]);
  }
}
//
// protected (initializer)
//
ShowPage_Edit.prototype.init = function(section, block) {
  this.section  = section !== undefined ? section : "";
  this.block    = block   !== undefined ? block   : "";
  this.rows     = 8;
  this.save     = "";
  this.textarea = window.document.getElementById(block);
  if (this.textarea) {
    this.textarea.initrows = this.rows = this.textarea.rows;
    this.textarea.manyrows = Math.min(5*this.rows, Math.max(this.rows, 20));
    this.save              = this.textarea.value;
    this.preview           = window.open("", "Preview_" + block, "", true);
  }
};
//
// public
//
ShowPage_Edit.prototype.sprint   = function() { return "ShowPage_Edit {" + this.toString() + "\n}"; };
ShowPage_Edit.prototype.toString = function() {
  var s = "";
  if (this.section !== undefined) s += "\n  [section] => " + this.section;
  if (this.block   !== undefined) s += "\n  [block]   => " + this.block;
  if (this.rows    !== undefined) s += "\n  [rows]    => " + this.rows;
  if (this.save    !== undefined) s += "\n  [save]    => " + this.save;
  return s;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class ShowPage_TextEdit                                                                            *
// *                                                                                                    *
// *   Text/HTML block to be edited (simultaneously with other blocks)                                  *
// *                                                                                                    *
// ******************************************************************************************************
//
// constructor
//
function ShowPage_TextEdit(url, user_id1, user_id2, section, blocks, rows) {
  if (arguments.length == 0 || url === null) {
  } else if (typeof url != "object") {
    this.init.apply(this, arguments);
  } else if (url instanceof ShowPage_TextEdit) {
    this.init(url.url, url.user_id1, url.user_id2, url.section, url.blocks, url.rows);
  } else /* if (url instanceof Array) */ {
    this.init(url['url'], url['user_id1'], url['user_id2'], url['section'], url['blocks'], url['rows']);
  }
}
//
// protected (initializer)
//
ShowPage_TextEdit.prototype.init = function(url, user_id1, user_id2, section, blocks, rows) {
  this.url         = url      !== undefined ? url      : "";
  this.user_id1    = user_id1 !== undefined ? user_id1 : "";
  this.user_id2    = user_id2 !== undefined ? user_id2 : "";
  this.section     = section  !== undefined ? section  : "";
  this.blocks      = blocks   !== undefined ? blocks   : "";
  this.rows        = rows     !== undefined ? rows     : 8;
  this.save_blocks = true;
  this.old_blocks  = {};
  this.new_blocks  = {};
  this.text_areas  = [];
};
//
// public
//
ShowPage_TextEdit.prototype.sprint   = function() { return "ShowPage_TextEdit {" + this.toString() + "\n}"; };
ShowPage_TextEdit.prototype.toString = function() {
  var s = "";
  if (this.url         !== undefined) s += "\n  [url]         => " + this.url;
  if (this.user_id1    !== undefined) s += "\n  [user_id1]    => " + this.user_id1;
  if (this.user_id2    !== undefined) s += "\n  [user_id2]    => " + this.user_id2;
  if (this.section     !== undefined) s += "\n  [section]     => " + this.section;
  if (this.save_blocks !== undefined) s += "\n  [save_blocks] => " + this.save_blocks;
  if (this.old_blocks  !== undefined) s += "\n  [old_blocks]  => (Object)";
  if (this.new_blocks  !== undefined) s += "\n  [new_blocks]  => (Object)";
  if (this.text_areas  !== undefined) s += "\n  [text_areas]  => (Array)";
  return s;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Simultaneous text/HTML multi-block editing functions (static)                                      *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.text_edit_list = {};

ShowPage.editBlocks = function(id, url, user_id1, user_id2, section, blocks, rows, eventObj) {
  ShowPage.text_edit_list[id] = new ShowPage_TextEdit(url, user_id1, user_id2, section, blocks, rows);
  ShowPage._editBlocks(id, eventObj);
  ShowPage.text_edit_list[id].save_blocks = false;
  return true;
};

ShowPage._editBlocks = function(id, eventObj) {
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  window.document.getElementById(id).innerHTML = '<a onclick="ShowPage._editBlocks(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Preview Changes"><img src="' + HOME + 'images/edit.gif" alt="Preview" align="absmiddle" border="0"></a>' + '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">' + '<a onclick="ShowPage.revertBlocks(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Discard Changes"><img src="' + HOME + 'images/withdraw.gif" alt="Revert" align="absmiddle" border="0"></a>' + '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">' + '<a onclick="ShowPage.saveBlocks(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Ready to save changes"><img src="' + HOME + 'images/accept.gif" alt="Save" align="absmiddle" border="0"></a>';
  var e = ShowPage.text_edit_list[id];
  //
  // Process all declared blocks that can be found, adding text-edit forms wherever possible.
  // Radio buttons are left alone, but their initial state is saved.  (Do we know what was their initial state?)
  //
  block = e.blocks.split(',');
  for (var i=0; i<block.length; i++) {
    var block_i = block[i].split(':');
    var rows_i  = block_i.length > 2 ? block_i[2] : e.rows;
    var block_i = block_i[0] + ':' + (block_i.length > 1 ? block_i[1] : 'content');
    var b = window.document.getElementById(block_i);
    if (b) {
      b.normalize();
      if (b.tagName.toLowerCase() == 'input' && b.type.toLowerCase() == 'radio') {
        //
        // Found a radio button with name and/or id = block_i.  (Remember to set both name and id.)
        // Find all radio buttons matching the block name, and set the value to the one that is checked.
        //
        var b = window.document.getElementsByName(block_i);
        if (e.save_blocks) e.old_blocks[block_i] = ''; // in case none is checked
        for (var j=0; j<b.length; j++) {
          if (e.save_blocks && b[j].checked) e.old_blocks[block_i] = b[j].value;
          b[j].style.visibility = 'inherit'; // should not work on MSIE, but it does
        }
        continue;
      }
      var t = window.document.getElementById('textarea_' + block_i);
      if (t) {
        //
        // Refresh the text.
        //
        b.innerHTML = t.value;
        b.normalize();
        t.value = b.innerHTML;
        b.parentNode.insertBefore(t, b);
      } else {
        //
        // Place a textarea before the text.
        //
        e.text_areas.push('textarea_' + block_i);
        var x = b.innerHTML;
        var t = window.document.createElement('TEXTAREA');
        b.parentNode.insertBefore(t, b);
        t.id              = 'textarea_' + block_i;
        if (navigator.appName.search(/Microsoft Internet Explorer/) != -1) {
          t.setAttribute("className", 'noprint');
          t.style.setAttribute("cssText", 'display:block; clear:both; width:100%;');
        } else {
          t.setAttribute("class", 'noprint');
          t.style.display = 'block';
          t.style.clear   = 'both';
          t.style.width   = '100%';
        }
        t.maxlength       = 1000000;
        t.rows            = rows_i;
        t.initrows        = rows_i;
        t.manyrows        = Math.min(5*rows_i, Math.max(rows_i, 20));
        t.onchange        = function(event) { for (id in ShowPage.text_edit_list) ShowPage._editBlocks(id, event); return true; }
        t.onfocus         = function(event) { return ShowPage.expandTextarea(event);  }
        t.onblur          = function(event) { return ShowPage.restoreTextarea(event); }
        t.value           = x;
        if (e.save_blocks) e.old_blocks[block_i] = t.value;
      }
    }
  }
  return true;
};

ShowPage.revertBlocks = function(id, eventObj) {
  //
  // Revert text to its initial contents.
  //
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  var e = ShowPage.text_edit_list[id];
  var block = e.blocks.split(',');
  for (var i=0; i<block.length; i++) {
    var block_i = block[i].split(':');
    var rows_i  = block_i.length > 2 ? block_i[2] : e.rows;
    var block_i = block_i[0] + ':' + (block_i.length > 1 ? block_i[1] : 'content');
    var b = window.document.getElementById(block_i);
    if (b) {
      b.normalize();
      if (b.tagName.toLowerCase() == 'input' && b.type.toLowerCase() == 'radio') {
        var b = window.document.getElementsByName(block_i);
        for (var j=0; j<b.length; j++) {
          b[j].checked = b[j].value == e.old_blocks[block_i];
          b[j].style.visibility = b[j].checked ? 'inherit' : 'hidden'; // should not work on MSIE, but it does
        }
      } else {
        var t = window.document.getElementById('textarea_' + block_i);
        t.parentNode.removeChild(t);
        b.innerHTML = e.old_blocks[block_i];
        e.text_areas.shift();
      }
    }
  }
  window.document.getElementById(id).innerHTML = '<a onclick="ShowPage._editBlocks(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Edit Text/HTML Blocks"><img src="' + HOME + 'images/edit.gif" alt="Edit" align="absmiddle" border="0"></a>';
  return true;
};

ShowPage.saveBlocks = function(id, eventObj) {
  //
  // Create a form to confirm and save the update of text.
  //
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  var e = ShowPage.text_edit_list[id];
  var block = e.blocks.split(',');
  for (var i=0; i<block.length; i++) {
    var block_i = block[i].split(':');
    var rows_i  = block_i.length > 2 ? block_i[2] : e.rows;
    var block_i = block_i[0] + ':' + (block_i.length > 1 ? block_i[1] : 'content');
    var b = window.document.getElementById(block_i);
    if (b) {
      b.normalize();
      if (b.tagName.toLowerCase() == 'input' && b.type.toLowerCase() == 'radio') {
        var b = window.document.getElementsByName(block_i);
        e.new_blocks[block_i] = '' // in case none is checked;
        for (var j=0; j<b.length; j++) {
          if (b[j].checked) e.new_blocks[block_i] = b[j].value;
          b[j].style.visibility = b[j].checked ? 'inherit' : 'hidden'; // should not work on MSIE, but it does
        }
      } else {
        var t = window.document.getElementById('textarea_' + block_i);
        e.new_blocks[block_i] = b.innerHTML = t.value;
        t.parentNode.removeChild(t);
      }
    }
  }
  if (e.section != '') {
    form =
      '<form action="' + e.url + '" method="post" enctype="multipart/form-data">' +
      '<input name="Section" type="hidden" value="UpdateText">' +
      '<input name="UserId1" type="hidden" value="' + e.user_id1 + '">' +
      '<input name="UserId2" type="hidden" value="' + e.user_id2 + '">' +
      '<input name="Sectn"   type="hidden" value="' + e.section + '">' +
      '<input name="Block"   type="hidden" value="';
    var n = 0;
    for (var i in e.new_blocks) if (e.new_blocks[i] != e.old_blocks[i]) {
      if (n++) form += ','; form += i;
    }
    form += '"><input name="UpdateText" type="submit" value="Save Changes" class="details" onclick="ShowPage.submitOnce(this,\'\',event)">';
    var n = 0;
    for (var i in e.new_blocks) if (e.new_blocks[i] != e.old_blocks[i]) form += '<textarea name="Block' + (n++) +
      '" style="position: absolute; visibility: hidden; left: 0px; top: 0px;">' + e.new_blocks[i] + '</textarea>';
    form += '</form>';
  }
  window.document.getElementById(id).innerHTML = n ? form :
   '<a onclick="ShowPage._editBlocks(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Edit Text/HTML Blocks"><img src="' + HOME + 'images/edit.gif" alt="Edit" align="absmiddle" border="0"></a>';
  return true;
};

ShowPage.restoreTextarea = function(eventObj) {
  //
  // Restore all editing textareas to their initial size.
  //
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  for (var id in ShowPage.edit_list) {
    var t = ShowPage.edit_list[id].textarea;
    if (t) t.rows = t.initrows;
  }
  for (var id in ShowPage.text_edit_list) {
    var e = ShowPage.text_edit_list[id];
    for (var i=0; i<e.text_areas.length; i++) {
      var t = window.document.getElementById(e.text_areas[i]);
      if (t) t.rows = t.initrows;
    }
  }
  return true;
};

ShowPage.expandTextarea = function(eventObj) {
  //
  // Expand this editing textarea and restore all others to their initial size.
  //
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  if (eventObj.target) t0 = eventObj.target;
  else if (eventObj.srcElement) t0 = eventObj.srcElement;
  else return true;
  for (var id in ShowPage.edit_list) {
    var t = ShowPage.edit_list[id].textarea;
    if (t) t.rows = t.id == t0.id ? t.manyrows : t.initrows;
  }
  for (var id in ShowPage.text_edit_list) {
    var e = ShowPage.text_edit_list[id];
    for (var i=0; i<e.text_areas.length; i++) {
      var t = window.document.getElementById(e.text_areas[i]);
      if (t) t.rows = t.id == t0.id ? t.manyrows : t.initrows;
    }
  }
  return true;
};

ShowPage.textareaRows = function(id, rows, eventObj) {
  //
  // Set the number of rows in this editing textarea.
  //
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  var t = window.document.getElementById(id);
  if (t) t.rows = rows;
  return true;
};

ShowPage.setValue = function(id, value, eventObj) {
  //
  // Set the value of an object.
  // E.g., set the value of <input name="whatever" id="something" type="hidden" value="">
  //
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  var o = window.document.getElementById(id);
  if (o) o.value = value;
  return true;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Generic text-editing functions (static)                                                            *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.edit_list = {};

ShowPage.editText = function(id, section, block) {
  ShowPage.edit_list[id] = new ShowPage_Edit(section, block);
  var t = window.document.getElementById(block);
  if (t && typeof t.onchange == "function") t.onchange();
};

ShowPage.editTextarea = function(id, eventObj) {
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  window.document.getElementById(id).innerHTML = '<a onclick="ShowPage.editTextarea(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Preview Changes"><img src="' + HOME + 'images/edit.gif" alt="Preview" align="absmiddle" border="0"></a>' + '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">' + '<a onclick="ShowPage.revertTextarea(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Discard Changes"><img src="' + HOME + 'images/withdraw.gif" alt="Revert" align="absmiddle" border="0"></a>' + '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">' + '<a onclick="ShowPage.saveTextarea(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Ready to save changes"><img src="' + HOME + 'images/accept.gif" alt="Save" align="absmiddle" border="0"></a>';
  var e = ShowPage.edit_list[id];
  if (e.textarea !== undefined) {
    e.textarea.rows          = e.rows;
    e.textarea.onfocus       = function(event) { return ShowPage.expandTextarea(event);  }
    e.textarea.onblur        = function(event) { return ShowPage.restoreTextarea(event); }
    e.textarea.style.display = 'block';                                  // should not work on MSIE, but it does
    if (typeof e.textarea.onchange == "function") e.textarea.onchange(); // should not work on MSIE, but it does
  }
  var preview = window.document.getElementById("Preview_" + e.block);
  if (preview) preview.style.display = 'block';                          // should not work on MSIE, but it does
  return true;
};

ShowPage.revertTextarea = function(id, eventObj) {
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  window.document.getElementById(id).innerHTML = '<a onclick="ShowPage.editTextarea(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Edit Text/HTML/XML Block"><img src="' + HOME + 'images/edit.gif" alt="Edit" align="absmiddle" border="0"></a>';
  var e = ShowPage.edit_list[id];
  if (e.textarea !== undefined) {
    e.textarea.rows          = e.rows;
    e.textarea.value         = e.save;
    e.textarea.onfocus       = null;
    e.textarea.onblur        = null;
    e.textarea.style.display = 'none';                                   // should not work on MSIE, but it does
    if (typeof e.textarea.onchange == "function") e.textarea.onchange(); // should not work on MSIE, but it does
  }
  return true;
};

ShowPage.saveTextarea = function(id, eventObj) {
  if (!eventObj) eventObj = window.event;
  if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  var e = ShowPage.edit_list[id];
  var save = e.textarea !== undefined && e.textarea.value != e.save;
  window.document.getElementById(id).innerHTML = save ?
    '<input name="UpdateText" type="submit" value="Save Changes" class="details" onclick="ShowPage.submitOnce(this,\'\',event)">' :
    '<a onclick="ShowPage.editTextarea(\'' + id.replace(/'/g,'\\\'') + '\',event)" onmouseover="editOver(event)" onmouseout="editOut(event)" title="Edit Text/HTML/XML Block"><img src="' + HOME + 'images/edit.gif" alt="Edit" align="absmiddle" border="0"></a>';
  if (e.textarea !== undefined) {
    e.textarea.rows          = e.rows;
    e.textarea.onfocus       = null;
    e.textarea.onblur        = null;
    e.textarea.style.display = 'none';                                   // should not work on MSIE, but it does
    if (typeof e.textarea.onchange == "function") e.textarea.onchange(); // should not work on MSIE, but it does
  }
  return true;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * XML-editing functions (static)                                                                     *
// *                                                                                                    *
// *   Editing functions for RDF, XSL, SVG, vCard, HTML.                                                *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.xmlParseErrorMessage = 'XML Parsing Error:\n\nThe XML code contains one or more errors.\nYou may edit the XML code and try again, or\nclick the red trashcan to revert to the original.';
ShowPage.showFragment = false;
//
// ******************************************************************************************************
// *                                                                                                    *
// * HTML-editing functions (static)                                                                    *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.renderHTML = function(id) {
  //
  // Render HTML in the id textarea as HTML in the Preview iframe.
  //
  var t = window.document.getElementById(id), p = null;
  if (t) for (var i in ShowPage.edit_list) if (ShowPage.edit_list[i].block == id) { p = ShowPage.edit_list[i].preview; break; }
  if (t && p) {
    //
    // Render the HTML.
    //
    p.document.open('text/html','replace');
    p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">', t.value, '</body></html>');
    p.document.close();
  }
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * RDF-editing functions (static)                                                                     *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.rdf_owlNS  = "http://www.w3.org/2002/07/owl#";
ShowPage.rdf_rdfNS  = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
ShowPage.rdf_rdfsNS = "http://www.w3.org/2000/01/rdf-schema#";
ShowPage.rdf_xsdNS  = "http://www.w3.org/2001/XMLSchema#";
ShowPage.rdf_xsNS   = "http://www.w3.org/TR/xmlschema-2#";
ShowPage.rdf_ccNS   = TRANSPORT+HOST+"/index.php?s=RDF#";
ShowPage.rdf_ccuNS  = TRANSPORT+HOST+"/index.php?s=RDF&amp;t=user#";
ShowPage.rdf_ccfNS  = TRANSPORT+HOST+"/index.php?s=RDF&amp;t=flow#";
ShowPage.rdf_cctNS  = TRANSPORT+HOST+"/index.php?s=RDF&amp;t=text#";
ShowPage.rdf_tags   = {
  "rdf:Alt"                          : "Alternative",
  "rdf:Bag"                          : "Bag",
  "rdf:Description"                  : "Description",
  "rdf:first"                        : "First Item",
  "rdf:li"                           : "List Item",
  "rdf:List"                         : "List",
  "rdf:nil"                          : "nil",
  "rdf:object"                       : "Object",
  "rdf:predicate"                    : "Predicate",
  "rdf:Property"                     : "Property",
  "rdf:RDF"                          : "RDF",
  "rdf:rest"                         : "Rest of Items",
  "rdf:Seq"                          : "Sequence",
  "rdf:Statement"                    : "Statement",
  "rdf:subject"                      : "Subject",
  "rdf:type"                         : "Type",
  "rdf:value"                        : "Value",
  "rdf:XMLLiteral"                   : "XML Literal Value",
  "rdf:_1"                           : "List Item 1",
  "rdf:_2"                           : "List Item 2",
  "rdf:_3"                           : "List Item 3",
  "rdf:_4"                           : "List Item 4",
  "rdf:_5"                           : "List Item 5",
  "rdf:_6"                           : "List Item 6",
  "rdf:_7"                           : "List Item 7",
  "rdf:_8"                           : "List Item 8",
  "rdf:_9"                           : "List Item 9",
  "rdf:_10"                          : "List Item 10",
  "rdfs:Class"                       : "Class",
  "rdfs:comment"                     : "Comment",
  "rdfs:Container"                   : "Container",
  "rdfs:ContainerMembershipProperty" : "Container Membership Property",
  "rdfs:Datatype"                    : "Datatype",
  "rdfs:domain"                      : "Domain",
  "rdfs:isDefinedBy"                 : "Is Defined By",
  "rdfs:label"                       : "Label",
  "rdfs:Literal"                     : "Literal Value",
  "rdfs:member"                      : "Member",
  "rdfs:range"                       : "Range",
  "rdfs:Resource"                    : "Resource",
  "rdfs:seeAlso"                     : "See Also",
  "rdfs:subClassOf"                  : "Sub-Class Of",
  "rdfs:subPropertyOf"               : "Sub-Property Of",
  "owl:AllDifferent"                 : "All Different",
  "owl:AnnotationProperty"           : "Annotation Property",
  "owl:Class"                        : "Class",
  "owl:DataRange"                    : "Data Range",
  "owl:DatatypeProperty"             : "Datatype Property",
  "owl:DeprecatedClass"              : "Deprecated Class",
  "owl:DeprecatedProperty"           : "Deprecated Property",
  "owl:FunctionalProperty"           : "Functional Property",
  "owl:InverseFunctionalProperty"    : "Inverse Functional Property",
  "owl:Nothing"                      : "Nothing",
  "owl:ObjectProperty"               : "Object Property",
  "owl:Ontology"                     : "Ontology",
  "owl:OntologyProperty"             : "Ontology Property",
  "owl:Restriction"                  : "Restriction",
  "owl:SymmetricProperty"            : "Symmetric Property",
  "owl:Thing"                        : "Thing",
  "owl:TransitiveProperty"           : "Transitive Property",
  "owl:allValuesFrom"                : "All Values From",
  "owl:backwardCompatibleWith"       : "Backward Compatible With",
  "owl:cardinality"                  : "Cardinality",
  "owl:complementOf"                 : "Complement Of",
  "owl:differentFrom"                : "Different From",
  "owl:disjointWith"                 : "Disjoint With",
  "owl:distinctMembers"              : "Distinct Members",
  "owl:equivalentClass"              : "Equivalent Class",
  "owl:equivalentProperty"           : "Equivalent Property",
  "owl:hasValue"                     : "Has Value",
  "owl:imports"                      : "Imports",
  "owl:incompatibleWith"             : "Incompatible With",
  "owl:intersectionOf"               : "Intersection Of",
  "owl:inverseOf"                    : "Inverse Of",
  "owl:maxCardinality"               : "Maximum Cardinality",
  "owl:minCardinality"               : "Minimum Cardinality",
  "owl:oneOf"                        : "One Of",
  "owl:onProperty"                   : "On Property",
  "owl:priorVersion"                 : "Prior Version",
  "owl:sameAs"                       : "Thing",
  "owl:someValuesFrom"               : "Some Values From",
  "owl:unionOf"                      : "Union Of",
  "owl:versionInfo"                  : "Version Information",
  "xs:anyType"                       : "xs:anyType",
  "xs:anySimpleType"                 : "xs:anySimpleType",
  "xs:string"                        : "xs:string",
  "xs:boolean"                       : "xs:boolean",
  "xs:decimal"                       : "xs:decimal",
  "xs:float"                         : "xs:float",
  "xs:double"                        : "xs:double",
  "xs:duration"                      : "xs:duration",
  "xs:dateTime"                      : "xs:dateTime",
  "xs:time"                          : "xs:time",
  "xs:date"                          : "xs:date",
  "xs:gYearMonth"                    : "xs:gYearMonth",
  "xs:gYear"                         : "xs:gYear",
  "xs:gMonthDay"                     : "xs:gMonthDay",
  "xs:gDay"                          : "xs:gDay",
  "xs:gMonth"                        : "xs:gMonth",
  "xs:hexBinary"                     : "xs:hexBinary",
  "xs:base64Binary"                  : "xs:base64Binary",
  "xs:anyURI"                        : "xs:anyURI",
  "xs:QName"                         : "xs:QName",
  "xs:NOTATION"                      : "xs:NOTATION",
  "xs:normalizedString"              : "xs:normalizedString",
  "xs:token"                         : "xs:token",
  "xs:language"                      : "xs:language",
  "xs:NMTOKEN"                       : "xs:NMTOKEN",
  "xs:NMTOKENS"                      : "xs:NMTOKENS",
  "xs:Name"                          : "xs:Name",
  "xs:NCName"                        : "xs:NCName",
  "xs:ID"                            : "xs:ID",
  "xs:IDREF"                         : "xs:IDREF",
  "xs:IDREFS"                        : "xs:IDREFS",
  "xs:ENTITY"                        : "xs:ENTITY",
  "xs:ENTITIES"                      : "xs:ENTITIES",
  "xs:integer"                       : "xs:integer",
  "xs:nonPositiveInteger"            : "xs:nonPositiveInteger",
  "xs:negativeInteger"               : "xs:negativeInteger",
  "xs:long"                          : "xs:long",
  "xs:int"                           : "xs:int",
  "xs:short"                         : "xs:short",
  "xs:byte"                          : "xs:byte",
  "xs:nonNegativeInteger"            : "xs:nonNegativeInteger",
  "xs:unsignedLong"                  : "xs:unsignedLong",
  "xs:unsignedInt"                   : "xs:unsignedInt",
  "xs:unsignedShort"                 : "xs:unsignedShort",
  "xs:unsignedByte"                  : "xs:unsignedByte",
  "xs:positiveInteger"               : "xs:positiveInteger",
  "c:CCData"                         : "CC Data",
  "c:uri"                            : "URI",
  "c:created"                        : "Created",
  "c:updated"                        : "Date Modified",
  "c:language"                       : "language",
  "c:type"                           : "type",
  "c:status"                         : "status",
  "c:boolean"                        : "boolean",
  "c:string"                         : "string",
  "c:uri_string"                     : "uri_string",
  "c:Timestamp"                      : "Timestamp",
  "c:Signature"                      : "Signature",
  "c:date"                           : "date",
  "c:user_id"                        : "user_id",
  "c:user_interface"                 : "user_interface",
  "c:letter_format"                  : "letter_format",
  "c:base64"                         : "base64",
  "c:value"                          : "value",
  "c:hours"                          : "hours",
  "c:dollars"                        : "dollars",
  "c:dollar_hr"                      : "dollar_hr",
  "c:ac_code"                        : "ac_code",
  "c:stars"                          : "stars",
  "c:c"                              : "code",
  "c:n"                              : "name",
  "c:v"                              : "value",
  "u:CCUser"                         : "CC User",
  "u:VCSHUser"                       : "VCSH User",
  "u:user_id"                        : "User ID",
  "u:short_name"                     : "Short Name",
  "u:full_name"                      : "Full Name",
  "u:status"                         : "Status",
  "u:type"                           : "Type",
  "u:last_login"                     : "Last Login",
  "u:password_salt"                  : "Password Salt",
  "u:password"                       : "Password",
  "u:access_from"                    : "Access From",
  "u:access_to"                      : "Access To",
  "u:SocialUser"                     : "Social User",
  "u:regy_id"                        : "Registry ID",
  "u:comm_id"                        : "Community ID",
  "u:time_value"                     : "Time Value",
  "u:deprec_time"                    : "Depreciation Time",
  "u:user_interface"                 : "User Interface",
  "u:letter_format"                  : "Letter Format",
  "u:image_type"                     : "Image Type",
  "u:image_data"                     : "Image Data",
  "f:CCFlow"                         : "CC Flow",
  "f:date"                           : "Date",
  "f:user_id1"                       : "User_id 1",
  "f:user_id2"                       : "User_id 2",
  "f:description"                    : "Description",
  "f:VCSHFlow"                       : "VCSH Flow",
  "f:AccessFlow"                     : "Access Flow",
  "f:SocialFlow"                     : "Social Flow",
  "f:status"                         : "Status",
  "f:type"                           : "Type",
  "f:give"                           : "Give",
  "f:type1"                          : "Account_type 1",
  "f:type2"                          : "Account_type 2",
  "f:ac_code"                        : "Access Code",
  "f:comm_id"                        : "Community_id",
  "f:details"                        : "Details",
  "f:note1"                          : "Thank-You Note 1",
  "f:note2"                          : "Thank-You Note 2",
  "f:value"                          : "Value",
  "t:CCText"                         : "CC Text",
  "t:SocialText"                     : "Social Text",
  "t:ValueItem"                      : "Value Item",
  "t:LETSplayItem"                   : "LETSplay Item",
  "t:title"                          : "Title",
  "t:content"                        : "Content",
  "t:VCSHText"                       : "VCSH Text",
  "t:status"                         : "Status",
  "t:type"                           : "Type",
  "t:section"                        : "Section",
  "t:block"                          : "Block",
  "t:user_id1"                       : "User_id 1",
  "t:user_id2"                       : "User_id 2",
  "t:value"                          : "Value",
  "t:local"                          : "Percent Local",
  "t:stars"                          : "Stars"
};

//
// Render RDF as HTML, emulating an XSL transformation.
//
ShowPage.showRDF = function(d, x, i) {
  if (d.write === undefined || x === null || typeof x != "object" || x.nodeType === undefined) return;
  if (i === undefined) i = 0;
  switch (x.nodeType)  {
  case 1 : // ELEMENT_NODE
    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\'font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
      d.write('<div class="details" style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 40px; text-indent: -30px; background-color: #f0f0f4;"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter;", monospace; font-size: 8pt\'>');
      break
    case "sourcetext" :
      d.write('<br>');
      break;
    case "rdf:RDF" :
      if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\' font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
      break;
    default :
      var x_attributes = '';
      if (x.attributes) for (var j=0; j<x.attributes.length; j++) x_attributes += ' ' + x.attributes.item(j).name + '="' + x.attributes.item(j).value + '"';
      if (ShowPage.rdf_tags[x.tagName]) {
        if (i == 1) d.write('<div style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 10px; background-color: #f0f0f4;"><span class="subheading">', ShowPage.rdf_tags[x.tagName], ':</span><span class="details"><span class="yes">', x_attributes, '</span></span>');
        else d.write('<br><span class="details" style="padding-left: ', 20*(i-1), 'px;"><span class="subheading">', ShowPage.rdf_tags[x.tagName], ' (</span><span class="results"><span class="yes">', x_attributes, '</span></span> ');
      } else d.write('<br><span class="details" style="padding-left: ', 20*(i-1), 'px;"><span class="subheading"><span class="no">', x.tagName, ' (</span></span><span class="results"><span class="yes">', x_attributes, '</span></span> ');
    }

    for (var y=x.firstChild; y; y=y.nextSibling) ShowPage.showRDF(d, y, i+1);

    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('</pre></div></div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</pre></div></body></html>');
        d.close();
      }
      break;
    case "sourcetext" :
      break;
    case "rdf:RDF" :
      if (ShowPage.showFragment) {
        d.write('</div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</body></html>');
        d.close();
      }
      break;
    default :
      if (ShowPage.rdf_tags[x.tagName]) {
        if (i == 1) d.write('</div>');
        else d.write(' </span><span class="subheading">)</span>');
      } else d.write(' </span><span class="subheading"><span class="no">)</span></span>');
    }
    break;
  case 3 : // TEXT_NODE
  case 4 : // CDATA_SECTION_NODE
    d.write(' ', ShowPage.htmlentities(x.data));
    break;
  }
};

ShowPage.renderRDF = function(id) {
  //
  // Render RDF in the id textarea as HTML in the Preview iframe.
  //
  var t = window.document.getElementById(id), p = null;
  if (t) for (var i in ShowPage.edit_list) if (ShowPage.edit_list[i].block == id) { p = ShowPage.edit_list[i].preview; break; }
  if (t && p) {
    var not_parsed = true;
    //
    // Parse the RDF.
    //
    if (not_parsed) {
      try {
        //
        // Wrap the RDF with an RDF header and footer.
        // MS Internet Explorer chokes on the RDF DTD, so we leave it out and globally replace the "&xsd;", "&xs;" and "&c;" entities.
        //
        var text = '<?xml version="1.0" encoding="utf-8"?><rdf:RDF xmlns:owl="' + ShowPage.rdf_owlNS + '" xmlns:rdf="' + ShowPage.rdf_rdfNS + '" xmlns:rdfs="' + ShowPage.rdf_rdfsNS + '" xmlns:xsd="' + ShowPage.rdf_xsdNS + '" xmlns:xs="' + ShowPage.rdf_xsNS + '" xmlns:c="' + ShowPage.rdf_ccNS + '" xmlns:u="' + ShowPage.rdf_ccuNS + '" xmlns:f="' + ShowPage.rdf_ccfNS + '" xmlns:t="' + ShowPage.rdf_cctNS + '">\n' + t.value.replace(/&xsd;/g,ShowPage.rdf_xsdNS).replace(/&xs;/g,ShowPage.rdf_xsNS).replace(/&c;/g,ShowPage.rdf_ccNS) + '\n</rdf:RDF>';
  
        //
        // MS Internet Explorer does it this way.
        //
        var d = null;
        for (var x in ShowPage.msXmlDocument) {
          try { d = new ActiveXObject(ShowPage.msXmlDocument[x]); }
          catch(err) { continue; }
          break;
        }
        if (d === null) throw "";
        d.async = false;
        d.loadXML(text);
        if (!d.documentElement) {
          //
          // An error was detected.  (MSIE does it this way.)
          //
          for (var dashes=''; dashes.length<d.parseError.linepos; dashes+='-');
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>', ShowPage.htmlentities(d.parseError.reason), '<br>Line Number ', d.parseError.line-1, ', Column ', d.parseError.linepos, ':<br> ', ShowPage.htmlentities(d.parseError.srcText), '<br>', dashes, '^</pre></body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) {
      try {
        //
        // Wrap the RDF with an XML/RDF header and footer.
        //
        var text = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE rdf:RDF [ <!ENTITY xsd "'+ShowPage.rdf_xsdNS+'"> <!ENTITY xs "'+ShowPage.rdf_xsNS+'"> <!ENTITY c "'+TRANSPORT+HOST+'/index.php?s=RDF#"> ]><rdf:RDF xmlns:owl="' + ShowPage.rdf_owlNS + '" xmlns:rdf="' + ShowPage.rdf_rdfNS + '" xmlns:rdfs="' + ShowPage.rdf_rdfsNS + '" xmlns:xsd="' + ShowPage.rdf_xsdNS + '" xmlns:xs="' + ShowPage.rdf_xsNS + '" xmlns:c="' + ShowPage.rdf_ccNS + '" xmlns:u="' + ShowPage.rdf_ccuNS + '" xmlns:f="' + ShowPage.rdf_ccfNS + '" xmlns:t="' + ShowPage.rdf_cctNS + '">\n' + t.value + '\n</rdf:RDF>';
        //
        // Other browsers do it this way.
        //
        var xmlParser = new DOMParser();
        try { var d = xmlParser.parseFromString(text, 'text/xml'); }
        catch(err) {
          //
          // An error was detected.  (Opera does it this way.)
          //
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 10pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error</span></span>');
          if (err.code) p.document.write('<br>code = ', err.code);
          p.document.write('</body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) return;

    //
    // Render the RDF as HTML.
    //
    ShowPage.showRDF(p.document, d.documentElement);

    if (d.documentElement.nodeType == 1 && d.documentElement.tagName == 'parsererror') {
      //
      // An error was detected.  (Firefox does it this way.)
      //
      alert(ShowPage.xmlParseErrorMessage);
      var m, lineNumber, column
      if (d.documentElement.firstChild && t.setSelectionRange &&
        (m = d.documentElement.firstChild.nodeValue.match(/Line Number (\d+), Column (\d+):/)) &&
        (lineNumber = parseInt(m[1],10)) > 1 && (column = parseInt(m[2],10)) > 0) {
        //
        // Highlight the offending XML fragment in the textarea.
        //
        for (var c=0, j=0; c>=0 && j<lineNumber-2; c++, j++) c = t.value.indexOf('\n', c);
        t.setSelectionRange(c, Math.min(t.value.length-1,c+column-1));
        t.focus();
      }
    }
  }
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * SVG-editing functions (static)                                                                     *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.svg_tags = {
  "a"                   : "Anchor",
  "altGlyph"            : "Alternative Glyph",
  "altGlyphDef"         : "Alternative Glyph Definition",
  "altGlyphItem"        : "Alternative Glyph Item",
  "animate"             : "Animate",
  "animateColor"        : "Animate Color",
  "animateMotion"       : "Animate Motion",
  "animateTransform"    : "Animate Transform",
  "circle"              : "Circle",
  "clipPath"            : "Clipping Path",
  "color-profile"       : "Color Profile",
  "cursor"              : "Cursor",
  "definition-src"      : "Definition Source",
  "defs"                : "Definitions",
  "desc"                : "Description",
  "ellipse"             : "Ellipse",
  "feBlend"             : "Filter: Blend",
  "feColorMatrix"       : "Filter: Color Matrix",
  "feComponentTransfer" : "Filter: Component Transfer",
  "feComposite"         : "Filter: Composite",
  "feConvolveMatrix"    : "Filter: Convolve Matrix",
  "feDiffuseLighting"   : "Filter: Diffuse Lighting",
  "feDisplacementMap"   : "Filter: Displacement Map",
  "feDistantLight"      : "Filter: Distant Light",
  "feFlood"             : "Filter: Flood",
  "feFuncA"             : "Filter: Alpha",
  "feFuncB"             : "Filter: Blue",
  "feFuncG"             : "Filter: Green",
  "feFuncR"             : "Filter: Red",
  "feGaussianBlur"      : "Filter: Gaussian Blur",
  "feImage"             : "Filter: Image",
  "feMerge"             : "Filter: Merge",
  "feMergeNode"         : "Filter: Merge Node",
  "feMorphology"        : "Filter: Morphology",
  "feOffset"            : "Filter: Offset",
  "fePointLight"        : "Filter: Point Light",
  "feSpecularLighting"  : "Filter: Specular Lighting",
  "feSpotLight"         : "Filter: Spot Light",
  "feTile"              : "Filter: Tile",
  "feTurbulence"        : "Filter: Turbulence",
  "filter"              : "Filter",
  "font"                : "Font",
  "font-face"           : "Font Face",
  "font-face-format"    : "Font Face Format",
  "font-face-name"      : "Font Face Name",
  "font-face-src"       : "Font Face Source",
  "font-face-uri"       : "Font Face URI",
  "foreignObject"       : "Foreign Object",
  "g"                   : "Group",
  "glyph"               : "Glyph",
  "glyphRef"            : "Glyph Reference",
  "hkern"               : "Horizontal Kern",
  "image"               : "Image",
  "line"                : "Line",
  "linearGradient"      : "Linear Gradient",
  "marker"              : "Marker",
  "mask"                : "Mask",
  "metadata"            : "Metadata",
  "missing-glyph"       : "Missing Glyph",
  "mpath"               : "Motion Path",
  "path"                : "Path",
  "pattern"             : "Pattern",
  "polygon"             : "Polygon",
  "polyline"            : "Polyline",
  "radialGradient"      : "Radial Gradient",
  "rect"                : "Rectangle",
  "script"              : "Script",
  "set"                 : "Set Attribute",
  "stop"                : "Stop",
  "style"               : "Style",
  "svg"                 : "SVG",
  "switch"              : "Switch",
  "symbol"              : "Symbol",
  "text"                : "Text",
  "textPath"            : "Text Path",
  "title"               : "Title",
  "tref"                : "Text Reference",
  "tspan"               : "Text Span",
  "use"                 : "Use",
  "view"                : "View",
  "vkern"               : "Vertical Kern"
};

//
// Render SVG as HTML, emulating an XSL transformation.
//
ShowPage.showSVG = function(d, x, i) {
  if (d.write === undefined || x === null || typeof x != "object" || x.nodeType === undefined) return;
  if (i === undefined) i = 0;
  switch (x.nodeType)  {
  case 1 : // ELEMENT_NODE
    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\'font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
      d.write('<div class="details" style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 40px; text-indent: -30px; background-color: #f0f0f4;"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>');
      break;
    case "sourcetext" :
      d.write('<br>');
      break;
    case "svg" :
      if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\'font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
      break;
    default :
      if (ShowPage.svg_tags[x.tagName]) {
        var x_attributes = '';
        if (x.attributes) for (var j=0; j<x.attributes.length; j++) x_attributes += ' ' + x.attributes.item(j).name + '="' + x.attributes.item(j).value + '"';
        if (i == 1) d.write('<div style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 10px; background-color: #f0f0f4;"><span class="subheading">', ShowPage.svg_tags[x.tagName], ':</span><span class="results"><span class="yes">', x_attributes, '</span></span>');
        else d.write('<br><span class="details" style="padding-left: ', 20*(i-1), 'px;"><span class="subheading">', ShowPage.svg_tags[x.tagName], ' (</span><span class="results"><span class="yes">', x_attributes, '</span></span> ');
      } else d.write('<br><span class="details" style="padding-left: ', 20*(i-1), 'px;"><span class="subheading"><span class="no">', x.tagName, ' (</span></span> ');
    }

    for (var y=x.firstChild; y; y=y.nextSibling) ShowPage.showSVG(d, y, i+1);

    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('</pre></div></div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</pre></div></body></html>');
        d.close();
      }
      break;
    case "sourcetext" :
      break;
    case "svg" :
      if (ShowPage.showFragment) {
        d.write('</div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</body></html>');
        d.close();
      }
      break;
    default :
      if (ShowPage.svg_tags[x.tagName]) {
        if (i == 1) d.write('</div>');
        else d.write(' </span><span class="subheading">)</span>');
      } else d.write(' </span><span class="subheading"><span class="no">)</span></span>');
    }
    break;
  case 3 : // TEXT_NODE
  case 4 : // CDATA_SECTION_NODE
    d.write(' ', ShowPage.htmlentities(x.data));
    break;
  }
};

ShowPage.renderSVG = function(id) {
  //
  // Render SVG in the id textarea as HTML in the Preview iframe.
  //
  var t = window.document.getElementById(id), p = null;
  if (t) for (var i in ShowPage.edit_list) if (ShowPage.edit_list[i].block == id) { p = ShowPage.edit_list[i].preview; break; }
  if (t && p) {
    var not_parsed = true;
    //
    // Parse the SVG.
    //
    if (not_parsed) {
      try {
        //
        // Wrap the XML with an SVG header and footer.
        // MS Internet Explorer chokes on the SVG DTD, so we leave it out.
        //
        text = '<?xml version="1.0" standalone="no"?><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n' + t.value + '\n</svg>';
        //
        // MS Internet Explorer does it this way.
        //
        var d = null;
        for (var x in ShowPage.msXmlDocument) {
          try { d = new ActiveXObject(ShowPage.msXmlDocument[x]); }
          catch(err) { continue; }
          break;
        }
        if (d === null) throw "";
        d.async = false;
        d.loadXML(text);
        if (!d.documentElement) {
          //
          // An error was detected.  (MSIE does it this way.)
          //
          for (var dashes=''; dashes.length<d.parseError.linepos; dashes+='-');
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>', ShowPage.htmlentities(d.parseError.reason), '<br>Line Number ', d.parseError.line-1, ', Column ', d.parseError.linepos, ':<br> ', ShowPage.htmlentities(d.parseError.srcText), '<br>', dashes, '^</pre></body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) {
      try {
        //
        // Wrap the SVG with an SVG header and footer.
        //
        var text = '<?xml version="1.0" standalone="no"?><!DOCTYPE SVG PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n' + t.value + '\n</svg>';
        //
        // Other browsers do it this way.
        //
        xmlParser = new DOMParser();
        try { var d = xmlParser.parseFromString(text, 'text/xml'); }
        catch(err) {
          //
          // An error was detected.  (Opera does it this way.)
          //
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 10pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error</span></span>');
          if (err.code) p.document.write('<br>code = ', err.code);
          p.document.write('</body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) return;

    //
    // Render the SVG as HTML.
    //
    ShowPage.showSVG(p.document, d.documentElement);

    if (d.documentElement.nodeType == 1 && d.documentElement.tagName == 'parsererror') {
      //
      // An error was detected.  (Firefox does it this way.)
      //
      alert(ShowPage.xmlParseErrorMessage);
      var m, lineNumber, column;
      if (d.documentElement.firstChild && t.setSelectionRange &&
        (m = d.documentElement.firstChild.nodeValue.match(/Line Number (\d+), Column (\d+):/)) &&
        (lineNumber = parseInt(m[1],10)) > 1 && (column = parseInt(m[2],10)) > 0) {
        //
        // Highlight the offending XML fragment in the textarea.
        //
        for (var c=0, j=0; c>=0 && j<lineNumber-2; c++, j++) c = t.value.indexOf('\n', c);
        t.setSelectionRange(c, Math.min(t.value.length-1,c+column-1));
        t.focus();
      }
    }
  }
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * vCard-editing functions (static)                                                                   *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.vCard_tags  = {
  "rdf:Alt"           : "Alternative",
  "rdf:Bag"           : "Bag",
  "rdf:Description"   : "Description",
  "rdf:first"         : "First Item",
  "rdf:li"            : "List Item",
  "rdf:List"          : "List",
  "rdf:nil"           : "nil",
  "rdf:object"        : "Object",
  "rdf:predicate"     : "Predicate",
  "rdf:Property"      : "Property",
  "rdf:RDF"           : "RDF",
  "rdf:rest"          : "Rest of Items",
  "rdf:Seq"           : "Sequence",
  "rdf:Statement"     : "Statement",
  "rdf:subject"       : "Subject",
  "rdf:type"          : "Type",
  "rdf:value"         : "Value",
  "rdf:XMLLiteral"    : "XML Literal Value",
  "rdf:_1"            : "List Item 1",
  "rdf:_2"            : "List Item 2",
  "rdf:_3"            : "List Item 3",
  "rdf:_4"            : "List Item 4",
  "rdf:_5"            : "List Item 5",
  "rdf:_6"            : "List Item 6",
  "rdf:_7"            : "List Item 7",
  "rdf:_8"            : "List Item 8",
  "rdf:_9"            : "List Item 9",
  "rdf:_10"           : "List Item 10",
  "vCard:ADR"         : "Address",
  "vCard:AGENT"       : "Agent",
  "vCard:BDAY"        : "Birthday",
  "vCard:CATEGORIES"  : "Categories",
  "vCard:CLASS"       : "Class",
  "vCard:Country"     : "Country",
  "vCard:EMAIL"       : "Email",
  "vCard:Extadd"      : "Extended Address",
  "vCard:Family"      : "Family Name",
  "vCard:FN"          : "Full Name",
  "vCard:GEO"         : "Geographical Information",
  "vCard:Given"       : "Given Name",
  "vCard:GROUP"       : "Group",
  "vCard:KEY"         : "Public Key",
  "vCard:LABEL"       : "Address Label",
  "vCard:Locality"    : "Locality",
  "vCard:LOGO"        : "Logo Image",
  "vCard:MAILER"      : "EMail Program",
  "vCard:N"           : "Name",
  "vCard:NAME"        : "vCard Name",
  "vCard:NICKNAME"    : "Short Name",
  "vCard:NOTE"        : "Note",
  "vCard:ORG"         : "Organization",
  "vCard:Orgname"     : "Organisation Name",
  "vCard:Orgunit"     : "Organisation Unit",
  "vCard:Other"       : "Other Names",
  "vCard:Pcode"       : "Postal Code",
  "vCard:PHOTO"       : "Photograph",
  "vCard:Pobox"       : "Post Office Box",
  "vCard:Prefix"      : "Prefix Name",
  "vCard:PRODID"      : "Product ID",
  "vCard:Region"      : "Region",
  "vCard:REV"         : "Revision",
  "vCard:ROLE"        : "Position Role",
  "vCard:SORT-STRING" : "Sort String",
  "vCard:SOUND"       : "Audio Sound",
  "vCard:SOURCE"      : "Source",
  "vCard:Suffix"      : "Suffix Name",
  "vCard:Street"      : "Street Address",
  "vCard:TEL"         : "Telephone",
  "vCard:TITLE"       : "Position Title",
  "vCard:TZ"          : "Timezone",
  "vCard:UID"         : "User ID",
  "vCard:URL"         : "URL",
  "ADR"               : "Address",
  "AGENT"             : "Agent",
  "BBS"               : "bbs",
  "BDAY"              : "Birthday",
  "BINVAL"            : "Binary Value",
  "CAR"               : "car",
  "CATEGORIES"        : "Categories",
  "CELL"              : "cell",
  "CLASS"             : "Class",
  "CONFIDENTIAL"      : "Confidential",
  "CRED"              : "Credential",
  "CTRY"              : "Country",
  "DESC"              : "Description",
  "DOM"               : "domestic",
  "EMAIL"             : "Email",
  "EXTADD"            : "Extended Address",
  "EXTVAL"            : "External Value",
  "FAMILY"            : "Family Name",
  "FAX"               : "fax",
  "FN"                : "Full Name",
  "GEO"               : "Geographical Information",
  "GIVEN"             : "Given Name",
  "HOME"              : "home",
  "INTERNET"          : "internet",
  "INTL"              : "international",
  "ISDN"              : "isdn",
  "JABBERID"          : "Jabber ID",
  "KEY"               : "Public Key",
  "KEYWORD"           : "Keyword",
  "LABEL"             : "Address Label",
  "LAT"               : "Latitude",
  "LINE"              : "Line",
  "LOCALITY"          : "Locality",
  "LOGO"              : "Logo Image",
  "LON"               : "Longitude",
  "MAILER"            : "EMail Program",
  "MIDDLE"            : "Middle Name",
  "MODEM"             : "modem",
  "MSG"               : "message",
  "N"                 : "Name",
  "NICKNAME"          : "Nickname",
  "NOTE"              : "Note",
  "NUMBER"            : "Number",
  "ORG"               : "Organisation",
  "ORGNAME"           : "Organisation Name",
  "ORGUNIT"           : "Organisation Unit",
  "PAGER"             : "pager",
  "PARCEL"            : "parcel",
  "PCODE"             : "Postal Code",
  "PCS"               : "pcs",
  "PHONETIC"          : "Phonetic",
  "PHOTO"             : "Photograph",
  "POBOX"             : "Post Office Box",
  "POSTAL"            : "postal",
  "PREF"              : "preferred",
  "PREFIX"            : "Prefix Name",
  "PRIVATE"           : "Private",
  "PRODID"            : "Product ID",
  "PUBLIC"            : "Public",
  "REGION"            : "Region",
  "REV"               : "Revision",
  "ROLE"              : "Position Role",
  "SORT-STRING"       : "Sort String",
  "SOUND"             : "Audio Sound",
  "STREET"            : "Street Address",
  "SUFFIX"            : "Suffix Name",
  "TEL"               : "Telephone",
  "TEXT"              : "text",
  "TITLE"             : "Position Title",
  "TYPE"              : "Type",
  "TZ"                : "Timezone",
  "UID"               : "User ID",
  "URL"               : "URL",
  "USERID"            : "User ID",
  "vCard"             : "vCard",
  "VERSION"           : "Version",
  "VIDEO"             : "video",
  "VOICE"             : "voice",
  "WORK"              : "work",
  "X400"              : "x400"
};

//
// Render vCard as HTML, emulating an XSL transformation.
//
ShowPage.showVCard = function(d, x, i) {
  if (d.write === undefined || x === null || typeof x != "object" || x.nodeType === undefined) return;
  if (i === undefined) i = 0;
  switch (x.nodeType)  {
  case 1 : // ELEMENT_NODE
    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\'font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'><div class="details" style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 40px; text-indent: -30px; background-color: #f0f0f4;"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
      d.write('<div class="details" style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 40px; text-indent: -30px; background-color: #f0f0f4;"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>');
      break;
    case "sourcetext" :
      d.write('<br>');
      break;
    case "rdf:RDF" :
    case "vCard"   :
      if (i) {
        // Nested vCard
      } else if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\'font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
    default :
      var x_attributes = '';
      if (x.attributes) for (var j=0; j<x.attributes.length; j++) x_attributes += ' ' + x.attributes.item(j).name + '="' + x.attributes.item(j).value + '"';
      if (ShowPage.vCard_tags[x.tagName]) {
        if (i == 0) d.write('<div style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 10px; background-color: #f0f0f4;"><span class="subheading">', ShowPage.vCard_tags[x.tagName], ':</span><span class="details"><span class="yes">', x_attributes, '</span></span>');
        else d.write('<br><span class="details" style="padding-left: ', 20*i, 'px;"><span class="subheading">', ShowPage.vCard_tags[x.tagName], ' (</span><span class="results"><span class="yes">', x_attributes, '</span></span> ');
      } else d.write('<br><span class="details" style="padding-left: ', 20*i, 'px;"><span class="subheading"><span class="no">', x.tagName, ' (</span></span><span class="results"><span class="yes">', x_attributes, '</span></span> ');
    }

    for (var y=x.firstChild; y; y=y.nextSibling) ShowPage.showVCard(d, y, i+1);

    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('</pre></div></div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</pre></div></body></html>');
        d.close();
      }
      break;
    case "sourcetext" :
      break;
    case "rdf:RDF" :
    case "vCard"   :
      if (ShowPage.vCard_tags[x.tagName]) {
        if (i == 0) d.write('</div>');
        else d.write(' </span><span class="subheading">)</span>');
      } else d.write(' </span><span class="subheading"><span class="no">)</span></span>');
      if (i) {
        // Nested vCard
      } else if (ShowPage.showFragment) {
        d.write('</div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</body></html>');
        d.close();
      }
      break;
    default :
      if (ShowPage.vCard_tags[x.tagName]) {
        if (i == 0) d.write('</div>');
        else d.write(' </span><span class="subheading">)</span>');
      } else d.write(' </span><span class="subheading"><span class="no">)</span></span>');
    }
    break;
  case 3 : // TEXT_NODE
  case 4 : // CDATA_SECTION_NODE
    d.write(' ', ShowPage.htmlentities(x.data));
    break;
  }
};

ShowPage.renderVCard = function(id) {
  //
  // Render vCard in the id textarea as HTML in the Preview iframe.
  //
  var t = window.document.getElementById(id), p = null;
  if (t) for (var i in ShowPage.edit_list) if (ShowPage.edit_list[i].block == id) { p = ShowPage.edit_list[i].preview; break; }
  if (t && p) {
    var not_parsed = true;
    //
    // Wrap the vCard with an XSL header and footer.
    //
    var text = '<?xml version="1.0" encoding="utf-8"?>\n' + t.value;
    //
    // Parse the vCard.
    //
    if (not_parsed) {
      try {
        //
        // MS Internet Explorer does it this way.
        //
        var d = null;
        for (var x in ShowPage.msXmlDocument) {
          try { d = new ActiveXObject(ShowPage.msXmlDocument[x]); }
          catch(err) { continue; }
          break;
        }
        if (d === null) throw "";
        d.async = false;
        d.loadXML(text);
        if (!d.documentElement) {
          //
          // An error was detected.  (MSIE does it this way.)
          //
          for (var dashes=''; dashes.length<d.parseError.linepos; dashes+='-');
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>', ShowPage.htmlentities(d.parseError.reason), '<br>Line Number ', d.parseError.line-1, ', Column ', d.parseError.linepos, ':<br> ', ShowPage.htmlentities(d.parseError.srcText), '<br>', dashes, '^</pre></body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) {
      try {
        //
        // Other browsers do it this way.
        //
        var xmlParser = new DOMParser();
        try { var d = xmlParser.parseFromString(text, 'text/xml'); }
        catch(err) {
          //
          // An error was detected.  (Opera does it this way.)
          //
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 10pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error</span></span>');
          if (err.code) p.document.write('<br>code = ', err.code);
          p.document.write('</body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) return;

    //
    // Render the vCard as HTML.
    //
    ShowPage.showVCard(p.document, d.documentElement);

    if (d.documentElement.nodeType == 1 && d.documentElement.tagName == 'parsererror') {
      //
      // An error was detected.  (Firefox does it this way.)
      //
      alert(ShowPage.xmlParseErrorMessage);
      var m, lineNumber, column;
      if (d.documentElement.firstChild && t.setSelectionRange &&
        (m = d.documentElement.firstChild.nodeValue.match(/Line Number (\d+), Column (\d+):/)) &&
        (lineNumber = parseInt(m[1],10)) > 1 && (column = parseInt(m[2],10)) > 0) {
        //
        // Highlight the offending XML fragment in the textarea.
        //
        for (var c=0, j=0; c>=0 && j<lineNumber-2; c++, j++) c = t.value.indexOf('\n', c);
        t.setSelectionRange(c, Math.min(t.value.length-1,c+column-1));
        t.focus();
      }
    }
  }
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * XSL-editing functions (static)                                                                     *
// *                                                                                                    *
// ******************************************************************************************************
//
ShowPage.xsl_xslNS = "http://www.w3.org/1999/XSL/Transform";
ShowPage.xsl_foNS  = "http://www.w3.org/1999/XSL/Format";
ShowPage.xsl_tags  = {
  "xsl:apply-imports"                      : "Apply Imports",
  "xsl:apply-templates"                    : "Apply Templates",
  "xsl:attribute"                          : "Attribute",
  "xsl:attribute-set"                      : "Attribute Set",
  "xsl:call-template"                      : "Call Template",
  "xsl:choose"                             : "Choose",
  "xsl:comment"                            : "Comment",
  "xsl:copy"                               : "Copy",
  "xsl:copy-of"                            : "Copy Of",
  "xsl:decimal-format"                     : "Decimal Format",
  "xsl:element"                            : "Element",
  "xsl:fallback"                           : "Fallback",
  "xsl:for-each"                           : "For Each",
  "xsl:if"                                 : "If",
  "xsl:import"                             : "Import",
  "xsl:include"                            : "Include",
  "xsl:key"                                : "Key",
  "xsl:message"                            : "Message",
  "xsl:namespace-alias"                    : "Namespace Alias",
  "xsl:number"                             : "Number",
  "xsl:otherwise"                          : "Otherwise",
  "xsl:output"                             : "Output",
  "xsl:param"                              : "Param",
  "xsl:preserve-space"                     : "Preserve Space",
  "xsl:processing-instruction"             : "Processing Instruction",
  "xsl:sort"                               : "Sort",
  "xsl:strip-space"                        : "Strip Space",
  "xsl:stylesheet"                         : "Stylesheet",
  "xsl:template"                           : "Template",
  "xsl:text"                               : "Text",
  "xsl:transform"                          : "Transform",
  "xsl:value-of"                           : "Value Of",
  "xsl:variable"                           : "Variable",
  "xsl:when"                               : "When",
  "xsl:with-param"                         : "With Parameter",
  "fo:bidi-override"                       : "Bi-Directionality Override",
  "fo:block"                               : "Block",
  "fo:block-container"                     : "Block Container",
  "fo:character"                           : "Character",
  "fo:character"                           : "Character",
  "fo:color-profile"                       : "Color Profile",
  "fo:conditional-page-master-reference"   : "Conditional Page-Master Reference",
  "fo:declarations"                        : "Declarations",
  "fo:external-graphic"                    : "External Graphic",
  "fo:float"                               : "Float",
  "fo:flow"                                : "Flow",
  "fo:footnote"                            : "Footnote",
  "fo:footnote-body"                       : "Footnote Body",
  "fo:initial-property-set"                : "Initial Property-Set",
  "fo:inline"                              : "Inline",
  "fo:inline-container"                    : "Inline Container",
  "fo:instream-foreign-object"             : "Instream Foreign Object",
  "fo:layout-master-set"                   : "Layout Master Set",
  "fo:leader"                              : "Leader",
  "fo:list-block"                          : "List Block",
  "fo:list-item"                           : "List Item",
  "fo:list-item-body"                      : "List-Item Body",
  "fo:list-item-label"                     : "List-Item Label",
  "fo:marker"                              : "Marker",
  "fo:multi-case"                          : "Multi Case",
  "fo:multi-properties"                    : "Multi Properties",
  "fo:multi-property-set"                  : "Multi Property Set",
  "fo:multi-switch"                        : "Multi Switch",
  "fo:multi-toggle"                        : "Multi Toggle",
  "fo:page-number"                         : "Page Number",
  "fo:page-number-citation"                : "Page-Number Citation",
  "fo:page-sequence"                       : "Page Sequence",
  "fo:page-sequence-master"                : "Page-Sequence Master",
  "fo:region-after"                        : "Region After",
  "fo:region-before"                       : "Region Before",
  "fo:region-body"                         : "Region Body",
  "fo:region-end"                          : "Region End",
  "fo:region-start"                        : "Region Start",
  "fo:repeatable-page-master-alternatives" : "Repeatable Page-Master Alternatives",
  "fo:repeatable-page-master-reference"    : "Repeatable Page-Master Reference",
  "fo:retrieve-marker"                     : "Retrieve Marker",
  "fo:root"                                : "Root",
  "fo:simple-link"                         : "Simple Link",
  "fo:simple-page-master"                  : "Simple Page-Master",
  "fo:single-page-master-reference"        : "Single Page-Master Reference",
  "fo:static-content"                      : "Static Content",
  "fo:table"                               : "Table",
  "fo:table-and-caption"                   : "Table and Caption",
  "fo:table-body"                          : "Table Body",
  "fo:table-caption"                       : "Table Caption",
  "fo:table-cell"                          : "Table Cell",
  "fo:table-column"                        : "Table Column",
  "fo:table-footer"                        : "Table Footer",
  "fo:table-header"                        : "Table Header",
  "fo:table-row"                           : "Table Row",
  "fo:title"                               : "Title",
  "fo:wrapper"                             : "Wrapper"
};

//
// Render XSL as HTML, emulating an XSL transformation.
//
ShowPage.showXSL = function(d, x, i) {
  if (d.write === undefined || x === null || typeof x != "object" || x.nodeType === undefined) return;
  if (i === undefined) i = 0;
  switch (x.nodeType)  {
  case 1 : // ELEMENT_NODE
    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\'font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'><div class="details" style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 40px; text-indent: -30px; background-color: #f0f0f4;"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
      d.write('<div class="details" style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 40px; text-indent: -30px; background-color: #f0f0f4;"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>');
      break;
    case "sourcetext" :
      d.write('<br>');
      break;
    case "xsl:stylesheet" :
      if (ShowPage.showFragment) {
        d.write('<link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"><div id="', ShowPage.showFragment, '" style=\'font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\'>');
      } else {
        d.open('text/html','replace');
        d.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8">');
      }
      break;
    default :
      var x_attributes = '';
      if (x.attributes) for (var j=0; j<x.attributes.length; j++) x_attributes += ' ' + x.attributes.item(j).name + '="' + x.attributes.item(j).value + '"';
      if (ShowPage.xsl_tags[x.tagName]) {
        if (i == 1) d.write('<div style="border: 1px solid #606060; margin: 10px 2px 10px 2px; padding: 10px 0px 10px 10px; background-color: #f0f0f4;"><span class="subheading">', ShowPage.xsl_tags[x.tagName], ':</span><span class="details"><span class="yes">', x_attributes, '</span></span>');
        else d.write('<br><span class="details" style="padding-left: ', 20*(i-1), 'px;"><span class="subheading">', ShowPage.xsl_tags[x.tagName], ' (</span><span class="results"><span class="yes">', x_attributes, '</span></span> ');
      } else d.write('<br><span class="details" style="padding-left: ', 20*(i-1), 'px;"><span class="subheading"><span class="no">', x.tagName, ' (</span></span><span class="results"><span class="yes">', x_attributes, '</span></span> ');
    }

    for (var y=x.firstChild; y; y=y.nextSibling) ShowPage.showXSL(d, y, i+1);

    switch (x.tagName) {
    case "parsererror" :
      if (ShowPage.showFragment) {
        d.write('</pre></div></div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</pre></div></body></html>');
        d.close();
      }
      break;
    case "sourcetext" :
      break;
    case "xsl:stylesheet" :
      if (ShowPage.showFragment) {
        d.write('</div>');
        ShowPage.showFragment = false;
      } else {
        d.write('</body></html>');
        d.close();
      }
      break;
    default :
      if (ShowPage.xsl_tags[x.tagName]) {
        if (i == 1) d.write('</div>');
        else d.write(' </span><span class="subheading">)</span>');
      } else d.write(' </span><span class="subheading"><span class="no">)</span></span>');
    }
    break;
  case 3 : // TEXT_NODE
  case 4 : // CDATA_SECTION_NODE
    d.write(' ', ShowPage.htmlentities(x.data));
    break;
  }
};

ShowPage.renderXSL = function(id) {
  //
  // Render XSL in the id textarea as HTML in the Preview iframe.
  //
  var t = window.document.getElementById(id), p = null;
  if (t) for (var i in ShowPage.edit_list) if (ShowPage.edit_list[i].block == id) { p = ShowPage.edit_list[i].preview; break; }
  if (t && p) {
    var not_parsed = true;
    //
    // Wrap the XSL with an XSL header and footer.
    //
    var text = '<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="' + ShowPage.xsl_xslNS + '" xmlns:fo="' + ShowPage.xsl_foNS + '">\n' + t.value + '\n</xsl:stylesheet>';
    //
    // Parse the XSL.
    //
    if (not_parsed) {
      try {
        //
        // MS Internet Explorer does it this way.
        //
        var d = null;
        for (var x in ShowPage.msXmlDocument) {
          try { d = new ActiveXObject(ShowPage.msXmlDocument[x]); }
          catch(err) { continue; }
          break;
        }
        if (d === null) throw "";
        d.async = false;
        d.loadXML(text);
        if (!d.documentElement) {
          //
          // An error was detected.  (MSIE does it this way.)
          //
          for (var dashes=''; dashes.length<d.parseError.linepos; dashes+='-');
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 8pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error:</span></span><pre class="details" style=\'font-family: "Lucida Sans Typewriter", monospace; font-size: 8pt;\'>', ShowPage.htmlentities(d.parseError.reason), '<br>Line Number ', d.parseError.line-1, ', Column ', d.parseError.linepos, ':<br> ', ShowPage.htmlentities(d.parseError.srcText), '<br>', dashes, '^</pre></body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) {
      try {
        //
        // Other browsers do it this way.
        //
        var xmlParser = new DOMParser();
        try { var d = xmlParser.parseFromString(text, 'text/xml'); }
        catch(err) {
          //
          // An error was detected.  (Opera does it this way.)
          //
          p.document.open('text/html','replace');
          p.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html style="background-color: #e8e8e8;"><head><link rel="stylesheet" href="', HOME, 'include/showPage.css" type="text/css"></head><body style=\'background-color: #e8e8e8; font-family: "Franklin Gothic Medium", sans-serif; font-size: 10pt;\' bgcolor="#e8e8e8"><span class="subheading"><span class="no">XML Parsing Error</span></span>');
          if (err.code) p.document.write('<br>code = ', err.code);
          p.document.write('</body></html>');
          p.document.close();
          alert(ShowPage.xmlParseErrorMessage);
          return;
        }
        not_parsed = false;
      }
      catch(err) { }
    }

    if (not_parsed) return;

    //
    // Render the XSL as HTML.
    //
    ShowPage.showXSL(p.document, d.documentElement);

    if (d.documentElement.nodeType == 1 && d.documentElement.tagName == 'parsererror') {
      //
      // An error was detected.  (Firefox does it this way.)
      //
      alert(ShowPage.xmlParseErrorMessage);
      var m, lineNumber, column;
      if (d.documentElement.firstChild && t.setSelectionRange &&
        (m = d.documentElement.firstChild.nodeValue.match(/Line Number (\d+), Column (\d+):/)) &&
        (lineNumber = parseInt(m[1],10)) > 1 && (column = parseInt(m[2],10)) > 0) {
        //
        // Highlight the offending XML fragment in the textarea.
        //
        for (var c=0, j=0; c>=0 && j<lineNumber-2; c++, j++) c = t.value.indexOf('\n', c);
        t.setSelectionRange(c, Math.min(t.value.length-1,c+column-1));
        t.focus();
      }
    }
  }
};
