<package>
  <job id="G2X">
  <?job debug="true"?>
  <runtime><description><![CDATA[GEDCOM one-to-one to XML: view source for usage and options ...]]></description></runtime>
  <script language="JScript" src="ANSELentify.js">
  // -----------------------------------------------------------------
  //~
  //~ GEDCOM one-to-one to XML for "Windows Script Host" (WSH)
  //~ USAGE: cscript //nologo ged1212xml.wsf [/name:value [...]] [<stdin.ged] [>stdout.xml] [2>stderr.log]
  //~ NOTES: double slashes for cscript-arguments, e.g. //nologo, single slashes for wsf-arguments
  //~        NCName represents XML "non-colonized" Names (no-colon constraint)
  //~ OPTIONS:
  //~   FILES
  //~     /ged:<file.ged>
  //~         GEDCOM input-filename, default=STDIN
  //~     /xml:<file.xml>
  //~         XML output-filename, default=STDOUT
  //~     /log:<file.log>
  //~         Logging output-filename, default=STDERR
  //~   GED-INPUT-ENCODING-MODE
  //~     /ans:true
  //~         start "ANSEL to Entity"-mode before 1st occurence of +n CHAR ANSEL
  //~   XML-OUTPUT
  //~     /nspfx:<ncname>
  //~         xml namespace prefix, requires setting of /uri:<URI> too, default=none
  //~     /nsuri:<URI>
  //~         xml namespace URI for xmlns[:nsPFX]="...", default=none
  //~     /enc:"iso-8859-1"|<encoding>
  //~         replace xml declaration's default <?xml ... encoding="iso-8859-1" ?>
  //~     /sty:<file.css|file.xsl>
  //~         insert processing-instruction <?xml-stylesheet ... href="..."?>, default=none
  //~     /root:"GED"|<ncname>
  //~         replace root-element's default tag-name "GED"
  //~     /id:"ID"|"xml:id"|<ncname>
  //~         replace attribute-name's default "ID" for GEDCOM's @<XREF>@s
  //~     /ref:"REF"|<ncname>
  //~         replace attribute-name's default "REF" for GEDCOM's @<XREF>@s
  //~     /dtd:""|<file.dtd>
  //~         insert doctype-definition <!DOCTYPE ... SYSTEM "...">, default=none
  //~     /xsd:""|<file.xsd>
  //~         insert root's xsi:XMLSchema-instance-location-definition, default=none
  //~     /idpfx=""|"id."|"ged-"|<ncname>
  //~         ID-prefix for valid xmlID/REF-values (NCNames), default=none
  //~         ID-prefix == string-additive, don't confuse it with namespace-prefixes!
  //~     /esc:""|"ESC"|<ncname>
  //~         given name ("ESC" preferred, default=none=noop) 
  //~         moves @#<DATE_CALENDAR_ESCAPE>@s into attributes
  //~     /sur:"SURN"|"S"|<ncname>|<!ncname>
  //~         alter node-name ("S" preferred, default="SURN") for slashed surname-part
  //~         to avoid double SURN-subnodes in an extended NAME-node/structure
  //~         a non-ncname char/string prevents slash-replacement at all
  //~     /pi:""|"attr"|"func"|"void"|"nopi"
  //~         predefined attribute- or function-style for processing-instructions
  //~         default="void" ~ empty for user-defined styles, otherwise plain style
  //~         a non-defined value (like "nopi") prevents PI-generation at all
  //~     /pincn:""|<ncname>
  //~         PI-ncname for processing-instruction-targetnames, default=none
  //~     /datepi:"DATE"|<ncname>|<!ncname>
  //~         processing-instruction-targetname, default="DATE" becomes <?DATE ...?>
  //~         date-format converted (if possible) to YYYY-MM-DD according to ISO 8601
  //~         a non-ncname char/string prevents DATE PI-generation
  //~     /uuidpi:"_UID"|"GUID"|"UUID"|"XUID"|"UURN"|"XURN"|<ncname>|<!ncname>
  //~         processing-instruction-targetname, default="UUID" becomes <?UUID ...?>
  //~         Universally Unique IDentifiers v4 (pseudo-random) according to RFC 4122
  //~         a standard-name is default-format for uuidsty-option 
  //~         a non-ncname char/string prevents UUID PI-generation
  //~     /_uidpi:"_UID"|"GUID"|"UUID"|"XUID"|"UURN"|"XURN"|<ncname>|<!ncname>
  //~         processing-instruction-targetname, default="_UID" becomes <?_UID_n ...?>
  //~         checks _UID-tag, default according to PAF-style UUID+Checksum (n=0|1|X)
  //~         a standard-name is default-format for _uidsty-option
  //~         a non-ncname char/string prevents _UID PI-generation
  //~     /uuidsty:<uuidPI-standard-targetname-format>|"UUID"|<targetformat>
  //~     /_uidsty:<_uidPI-standard-targetname-format>|"_UID"|<targetformat>
  //~         default-format-1 : targetname of PI if predef'd standard-format
  //~         default-format-2 : formatname "[_U]UID" if PI-name is non-standard
  //~         default-format-3 : else-clause-format if user-def'd is non-standard
  //~         "_UID" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXCCCC (_uidsty-default)
  //~                PAF-GEDCOM-_UID 16+2 bytes, 36 chars uppercase hexdigit with checksum
  //~         "UUID" xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (uuidsty-default)
  //~                RFC-4122-UUIDv4 16 bytes, 32+4 chars lowercase hexdigit hyphen-grouped
  //~         "GUID" {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
  //~                embraced {UUIDv4} 16 bytes, 32+6 chars uppercase hexdigit hyphen-grouped
  //~         "XUID" {XxxxXXXx-XXxX-xXXx-xxXX-XxXxxXXXxXxX}cccc
  //~                extended mixedcase and -style {GUIDv4}, 4-hexdigit checksum appended
  //~         "UURN" urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  //~                prefixed lowercase "urn:uuid:UUIDv4" (RFC-4122, UUID as URN)
  //~         "XURN" urn:uuid:XXXxxXxX-xxXx-XxXX-XXXX-xXXXXXxXxxxX+cccc
  //~                extended mixedcase "urn:uuid:UUIDv4+checksum" (RFCs 2141+3986+4122)
  //~          else: xXxXXxXX-xXXx-XXxx-XxxX-xxxxXXxxXxxX cccc
  //~                combined mixedcase UUIDv4 with 4-hexdigit checksum (set apart)
  //~     /seed:noop
  //~         built-in random() not seedable in ECMAScript
  //~
  // -----------------------------------------------------------------
  //~
  //~ Copyright (c) 2008 ff. Stefan Unterstein <http://www.unterstein.net/ged1212xml>
  //~
  //~ By operation of rights, permission is hereby granted to copy, distribute and/or 
  //~ modify this program under the terms of the GNU General Public License Version 3 
  //~ or any later version published by the Free Software Foundation. See the current 
  //~ License at <http://www.gnu.org/licenses/gpl.html> for more details.
  //~
  //~ Such free(d) "copylefted" software is distributed 
  //~ WITHOUT ANY WARRANTY OF OR ABOUT ANYTHING but the "copyleft" itself.
  //~
  // -----------------------------------------------------------------
  </script>
  <script language="JScript">
  // -----------------------------------------------------------------
  //~ UUID-code derived and varied from
  //~ https://github.com/broofa/node-uuid
  //~ http://www.broofa.com/Tools/Math.uuid.js
  //~ http://www.broofa.com/2008/09/javascript-uuid-function/
  //~ http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
  //~ UUID-spec http://tools.ietf.org/html/rfc4122.html
  //~ diff.spec.: output of randomly mixed-case letters
  // -----------------------------------------------------------------
  
  var xcharX = "89AB89ab01234567cdef01234567CDEF".split(""); // 31 random() per UUID, miXed case
- var uuid4X = function() { 
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function($0){ return xcharX[0|Math.random()*{"x":32,"y":8}[$0]]; }); 
      }
- var uuid4x = function() { 
      return ("xxxxxxxx-xxxx-4xxx-"+xcharX[0|Math.random()*8]+"xxx-xxxxxxxxxxxx").replace(/x/g, function(){ return xcharX[0|Math.random()*32]; }); 
      }
- var uuid4v = function() { // 5 random() assignments per UUID, miXed case
      var r, c=xcharX;
      return [
          c[(r=Math.random()*0x100000000)&0x1f], // 5 bits for val./pos.0-31
          c[(r>>> 5)&0x1f],
          c[(r>>>10)&0x1f],
          c[(r>>>15)&0x1f],
          c[(r>>>20)&0x1f],
          c[(r>>>25)&0x1f],
          c[(r=Math.random()*0x100000000)&0x1f],
          c[(r>>> 5)&0x1f],
          "-",
          c[(r>>>10)&0x1f],
          c[(r>>>15)&0x1f],
          c[(r>>>20)&0x1f],
          c[(r>>>25)&0x1f],
          "-",
          "4",
          c[(r=Math.random()*0x100000000)&0x1f],
          c[(r>>> 5)&0x1f],
          c[(r>>>10)&0x1f],
          "-",
          c[(r>>>15)&0x07], // use 3 of 5 bits for val./pos.0-7 of [8,9,A,B,8,9,a,b,...
          c[(r>>>17)&0x1f], // re-use 1 of prev.3 bits (6*5+2=32 bits available)
          c[(r>>>22)&0x1f],
          c[(r>>>27)&0x1f],
          "-",
          c[(r=Math.random()*0x100000000)&0x1f],
          c[(r>>> 5)&0x1f],
          c[(r>>>10)&0x1f],
          c[(r>>>15)&0x1f],
          c[(r>>>20)&0x1f],
          c[(r>>>25)&0x1f],
          c[(r=Math.random()*0x100000000)&0x1f],
          c[(r>>> 5)&0x1f],
          c[(r>>>10)&0x1f],
          c[(r>>>15)&0x1f],
          c[(r>>>20)&0x1f],
          c[(r>>>25)&0x1f]
      ].join("");
  }
  
  // -----------------------------------------------------------------
  //~ http://wiki-de.genealogy.net/UID-Tag
  //~ http://www.tamurajones.net/The_UIDTag.xhtml
  //~ https://devnet.familysearch.org/docs/gedcom/GEDCOMUniqueIdentifiers.pdf
  // -----------------------------------------------------------------
  
- var uuid4matter = function(UUID,fmt) {
      var BytesSum1 = 0, ChecksB17 = 0;
      var BytesSum2 = 0, ChecksB18 = 0;
      var JointUUID = UUID.split("-").join("").substr(0,32);
      for (var n=0; n<16; n++) 
-     {
          BytesSum1 += parseInt(JointUUID.substr(n*2,2),16);
          BytesSum2 += BytesSum1;
      }
          ChecksB17 = BytesSum1 % 256;
          ChecksB18 = BytesSum2 % 256;
      var ChecksHex = (ChecksB17<16?"0":"") + ChecksB17.toString(16) + (ChecksB18<16?"0":"") + ChecksB18.toString(16);
      var CanonUUID = JointUUID.substr(0,8)+"-"+JointUUID.substr(8,4)+"-"+JointUUID.substr(12,4)+"-"+JointUUID.substr(16,4)+"-"+JointUUID.substr(20,12);
      switch (fmt||"")
-     {
          case "XUID" : return "{" + CanonUUID + "}" + ChecksHex;
          case "XURN" : return "urn:uuid:" + CanonUUID + "+" + ChecksHex;
          case "UURN" : return "urn:uuid:" + CanonUUID.toLowerCase();
          case "_UID" : return (JointUUID + ChecksHex).toUpperCase();
          case "GUID" : return "{" + CanonUUID.toUpperCase() + "}";
          case "UUID" : return CanonUUID.toLowerCase();
          default     : return CanonUUID + " " + ChecksHex;
      }
  }
  
  function gedPIUUID(target) { return xmlPI(target,uuid4matter(uuid4v(),uuidSTY)); }
  
  var RExurn = /(?:urn:uuid:)?/i;
  var RExuid = /(\{?[0-9a-f]{2}(?:-?[0-9a-f]{2}){14}-?[0-9a-f]{2}\}?(?:[- +]?[0-9a-f]{2}-?[0-9a-f]{2})?)/i;
  
- function gedPI_UID(arg_UID) {
      var gvn_UID = RExuid.test(arg_UID) ? (RegExp.$1).replace(/[-{ }+]/g,"") : "" ;
      if (gvn_UID)
-     {
          //~ var val_UID = (gvn_UID.length>=32) ? gvn_UID.substr(0,32) : "" ;
          //~ var chk_UID = (gvn_UID.length==36) ? gvn_UID.substr(32,4) : "" ;
          var cmp_UID = uuid4matter(gvn_UID,_uidSTY);  
          if (arg_UID==cmp_UID)
-         {
              return xmlPI(_uidPI+"_1",cmp_UID);
              //
              //  true _uidSTY-format and value, comp'd and given ID+checksum are identical
              //  if _UID-style (default), value and format are likely to be accepted by PAF-compatibles
              //
          } else {
              return xmlPI(_uidPI+"_X",cmp_UID);
              //
              //  true UUID 128-bit value, but false format or checksum, or surplus characters 
              //  value now preserved and transformed into _uidSTY-format, accordingly plus new checksum 
              //  if _UID-style and not eXchanged, this and next are likely to be rejected by PAF-compatibles
              //
          }                           
      } else {
          return xmlPI(_uidPI+"_0",uuid4matter(uuid4v(),_uidSTY));
          //
          //  false, no (valid) UUID or 128-bit-value available, new UUID in _uidSTY-format generated
          //
      }
  }
  
  // -----------------------------------------------------------------
  // -----------------------------------------------------------------
  </script>
  <script language="JScript">
  // -----------------------------------------------------------------
  // parse args, echo usage
  // -----------------------------------------------------------------
  
  var oArgs = WScript.Arguments;
  var nArgs = WScript.Arguments.Named;    //  /name:value 
  var uArgs = WScript.Arguments.Unnamed;
  var Usage = "Usage: cscript \/\/NoLogo [\/\/job:G2X] [absPath]"+WScript.ScriptName+" [\/ged:|\/xml:|\/log:[\"]file.ged|.xml|.log[\"]] [< stdin.ged] [> stdout.xml] [2> stderr.log] \n... view source for more options";
  
  if (uArgs.length || nArgs.length>24 || oArgs.length!=nArgs.length) { WScript.Echo(Usage); WScript.Quit(1); }
  
  var aName = { "ged":"", "xml":"", "log":"", "nspfx":"", "nsuri":"", "enc":"", "sty":"", "root":"", "id":"", "ref":"", "dtd":"", "xsd":"", "idpfx":"", "pi":"", "pincn":"", "esc":"", "sur":"", "ans":"", "datepi":"", "uuidpi":"", "_uidpi":"", "_uidsty":"", "uuidsty":"", "seed":"" };
  
  if (nArgs.length) // case-insensitive for NAME in /NAME:value pairs if lowercase name-key in aName-Object
- {
-     for (var idx=0; idx<oArgs.length; idx++) {
          if (/^\/(\w+?):/.test(oArgs(idx)) && nArgs.Exists(RegExp.$1) && ((RegExp.$1).toLowerCase() in aName)) aName[(RegExp.$1).toLowerCase()]=nArgs.Item(RegExp.$1);
      }
  }
- /*
  if (nArgs.length) // name-key case-sensitive for NAME in /NAME:value pairs 
  {
      for (var idx in aName) { if (nArgs.Exists(idx)) aName[idx]=nArgs.Item(idx); }
  }
  */
  
  var FSO = new ActiveXObject("Scripting.FileSystemObject");
- var aFile = {
      "ged" : ( (aName.ged) ? FSO.OpenTextFile   (aName.ged, 1)    : WScript.StdIn  ),
      "xml" : ( (aName.xml) ? FSO.CreateTextFile (aName.xml, true) : WScript.StdOut ),
      "log" : ( (aName.log) ? FSO.CreateTextFile (aName.log, true) : WScript.StdErr )
  }
  
  aName.ged = aName.ged||"STDIN";
  aName.xml = aName.xml||"STDOUT";
  aName.log = aName.log||"STDERR";
  
  var REncname    = /^[a-z_A-Z][-a-z_A-Z.0-9]*$/;
  var REncnORnone = /^$|^[a-z_A-Z][-a-z_A-Z.0-9]*$/;
  
- if (aName.nspfx && !aName.nsuri) {
      WScript.StdErr.WriteLine("Error: xmlNamespace \/nspfx:Prefix w\/o \/nsuri:URI\n"+Usage); WScript.Quit(1);
  }
- if (!REncnORnone.test(aName.nspfx) || !REncnORnone.test(aName.idpfx) || !REncnORnone.test(aName.pincn)) {
      WScript.StdErr.WriteLine("Error: (nspfx|idpfx|pincn) require a valid NCName\n"+Usage); WScript.Quit(1);
  }
  
  // -----------------------------------------------------------------
  // -----------------------------------------------------------------
  
  var $AP = Array.prototype; // var args = [].slice.call(arguments,0);
  String.prototype.attr   = function(NMTOKEN) { return (this.valueOf())?" "+NMTOKEN+"=\""+this+"\"":""; }
  String.prototype.func   = function(NMTOKEN) { return (this.valueOf())?" "+NMTOKEN+"(\""+this+"\");":""; }
  String.prototype["void"]= function(NMTOKEN) { return (this.valueOf())?" "+this:""; }
  String.prototype.mark   = function(NMTOKEN) { return (this.valueOf())?"<"+NMTOKEN+">"+this+"<\/"+NMTOKEN+">":"<"+NMTOKEN+" \/>"; }
  String.prototype.markup = function(/*NMTOKENS*/) { return  "<"+$AP.join.call(arguments,"><")+">"+this+"<\/"+$AP.slice.call(arguments,0).reverse().join("><\/")+">"; }
  String.prototype.markUP = function(/*NMTOKENS*/) { return ["<",$AP.join.call(arguments,"><"),">",this,"<\/",$AP.slice.call(arguments,0).reverse().join("><\/").replace(/\s+[^>]*/gi,""),">"].join(""); }
  String.prototype.entify = function() { return (this.valueOf())?this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):this; }
  Boolean.prototype.attr  = String.prototype.attr;
  Boolean.prototype.func  = String.prototype.func;
  Boolean.prototype.mark  = String.prototype.mark;
  
  var Report = ['@@report'];
- var updateReport = function(s) {
      if (s instanceof Array) Report=Report.concat(s);
      else if ((typeof(s)=='string')||(s instanceof String)) Report[Report.length]=s; }
- var returnReport = function() {
      return Report.join('\r\n')+'\r\n@@\r\n'; }
  
  // -----------------------------------------------------------------
  // -----------------------------------------------------------------
  
  var gedFile      = aFile.ged;
  var gedFileName  = aName.ged;
  var xmlFile      = aFile.xml;
  var xmlFileName  = aName.xml;
  var logFile      = aFile.log;
  var logFileName  = aName.log;
  
  var xmlEnc       = aName.enc||"iso-8859-1";
  var xmlStyle     = (/\.(css|xsl)$/i.test(aName.sty)) ? "\n<?xml-stylesheet type=\"text\/"+(RegExp.$1).toLowerCase()+"\" href=\""+aName.sty+"\"?>" : "" ;
  var xmlRoot      = aName.root||"GED";
  var xmlID        = aName.id||"ID";
  var xmlIDREF     = aName.ref||"REF";
  var xmlnsATTR    = (aName.nsuri) ? ((aName.nspfx) ? " xmlns:"+aName.nspfx+"=\""+aName.nsuri+"\"" : " xmlns=\""+aName.nsuri+"\"") : "" ;
  var xmlnsPFX     = (aName.nspfx) ? aName.nspfx+":" : "" ;
  var xmlDTD       = (aName.dtd) ? "\n<!DOCTYPE "+xmlnsPFX+xmlRoot+" SYSTEM \""+aName.dtd+"\">" : "" ;
  var xsiXSD       = (aName.xsd) ? " xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\""+((aName.uri) ? " xsi:schemaLocation=\""+aName.uri+" " : " xsi:noNamespaceSchemaLocation=\"")+aName.xsd+"\"" : "" ;
  var encANSEL     = Boolean(aName.ans)||false; 
  if (encANSEL) { updateReport("GEDCOM input-encoding preset to ANSEL"); }
  var surNAME      = (aName.sur!="") ? ((/^[a-zA-Z_]\w*$/.test(aName.sur)) ? aName.sur : "") : "SURN" ;
  var escDATE      = aName.esc||"";
  var idPFX        = aName.idpfx||"";
  var piNCN        = aName.pincn||"";
  var piSTY        = (/^(?:attr|func|void)$/.test(aName.pi)) ? aName.pi : (aName.pi=="") ? "void" : "" ;
  var datePI       = (aName.datepi!="") ? ((REncname.test(aName.datepi)) ? aName.datepi : "") : "DATE" ;
  var uuidPI       = (aName.uuidpi!="") ? ((REncname.test(aName.uuidpi)) ? aName.uuidpi : "") : "UUID" ;
  var _uidPI       = (aName._uidpi!="") ? ((REncname.test(aName._uidpi)) ? aName._uidpi : "") : "_UID" ;
  var _uidSTY      = (aName._uidsty) ? aName._uidsty : ((/^(?:[_GUX]UID|[UX]URN)$/.test(_uidPI)) ? _uidPI : "_UID") ;
  var uuidSTY      = (aName.uuidsty) ? aName.uuidsty : ((/^(?:[_GUX]UID|[UX]URN)$/.test(uuidPI)) ? uuidPI : "UUID") ;
  var piSET        = { "attr":{ "ncn":piNCN||xmlRoot }, "func":{ "ncn":piNCN||xmlRoot }, "void":{ "ncn":piNCN||"" } }
  
- var GEDCOM = function(LineStr,LineNum) {
      this.Line  = LineStr;
      this.LNum  = LineNum;
      this.Valid = /\s*([0-9][0-9]?)\s+([a-zA-Z0-9_@]\S*)(?:$|\s+)(.*)/.test(this.Line);
      this.Level = (isNaN(RegExp.$1)) ? 0 : parseInt(RegExp.$1,10);
      this.Token = RegExp.$2;
      this.Value = (RegExp.$3) ? (RegExp.$3).entify().replace(/@@/g,"@") : false ;
      this.Value = (this.Value && encANSEL) ? ANSELentify(this.Value) : this.Value ;
      this.Id    = (/^@([a-zA-Z_0-9]\S*)@$/.test(this.Token)) ? idPFX+RegExp.$1 : false ;
      this.IdRef = (/^@([a-zA-Z_0-9]\S*)@$/.test(this.Value)) ? (this.Value=false,idPFX+RegExp.$1) : false ;
      this.PI    = (this.Level==0 && this.Id && piSTY && uuidPI) ? gedPIUUID(uuidPI) : "" ;
      return this;
  }
  
  var gedPrev = new GEDCOM("0 NULL", 0); 
      gedPrev.Level = -1;
      gedPrev.Token = "";
      gedPrev.Value = false;
      gedPrev.Id    = false;
      gedPrev.IdRef = false;
      gedPrev.PI    = "";
  
  var tagStack = [];
  var tabDepth = [""]; for (var i=1; i<99; i++) tabDepth[i]=tabDepth[i-1]+"  ";
  // var tabDepth = ["","\t","\t\t","\t\t\t","\t\t\t\t","\t\t\t\t\t","\t\t\t\t\t\t","\t\t\t\t\t\t\t","\t\t\t\t\t\t\t\t","\t\t\t\t\t\t\t\t\t"];
  
- function xmlClosings(gedLevel,gedPrev) {
      if (gedLevel> gedPrev.Level) { xmlFile.WriteLine((gedPrev.Value)?"":">"); return; }
      if (gedLevel==gedPrev.Level) { xmlFile.WriteLine((gedPrev.Value)?tagStack[gedPrev.Level]:"/>"+gedPrev.PI); return; }
-     if (gedLevel <gedPrev.Level) {
          xmlFile.WriteLine((gedPrev.Value)?tagStack[gedPrev.Level]:"/>"+gedPrev.PI);
-         for (var lvl=gedPrev.Level-1; lvl>=gedLevel; lvl--) {
              xmlFile.WriteLine(tabDepth[lvl]+tagStack[lvl]);
          }
      }
  }
  
  function xmlPI(target, value)
- {
      return "<?" +  (piSET[piSTY].ncn||target) + value[piSTY](target) + "?>";
  }
  
  var mm = { "JAN":"-01-", "FEB":"-02-", "MAR":"-03-", "APR":"-04-", "MAY":"-05-", "JUN":"-06-", "JUL":"-07-", "AUG":"-08-", "SEP":"-09-", "OCT":"-10-", "NOV":"-11-", "DEC":"-12-" };
  
- function gedPIDATE(DATE) { // ISO: YYYY-MM-DD
-     if (/^([0-3]?[0-9])\s+(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\s+([0-9]?[0-9]?[0-9]?[0-9])$/.test(DATE)) {
          return xmlPI(datePI, [["0000","000","00","0",""][(RegExp.$3).length], RegExp.$3, mm[RegExp.$2], ["00","0",""][(RegExp.$1).length], RegExp.$1].join(""));
      }
-     if (/^(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\s+([0-9]?[0-9]?[0-9]?[0-9])$/.test(DATE)) {
          return xmlPI(datePI, [["0000","000","00","0",""][(RegExp.$2).length], RegExp.$2, mm[RegExp.$1], "00"].join(""));
      }
-     if (/^([0-9]?[0-9]?[0-9]?[0-9])$/.test(DATE)) { 
          return xmlPI(datePI, [["0000","000","00","0",""][(RegExp.$1).length], RegExp.$1, "-00-00"].join(""));
      }
      return "";
  }
  
  // -----------------------------------------------------------------
  // -----------------------------------------------------------------
  
  xmlFile.WriteLine("<?xml version=\"1.0\" encoding=\""+xmlEnc+"\"?>"+xmlStyle);
  xmlFile.WriteLine("<!-- ================================================= -->");
  xmlFile.WriteLine("<!-- GEDCOM one-to-one to XML by ged1212xml.wsf (StUs) -->");
  xmlFile.WriteLine("<!-- script source at http:\/\/unterstein.net\/ged1212xml -->");
  xmlFile.WriteLine("<!-- ================================================= -->"+xmlDTD);
  xmlFile.Write    ("<"+xmlnsPFX+xmlRoot+xmlnsATTR+xsiXSD);
  gedRead:
      while (!gedFile.AtEndOfStream)
-     {
          var ged$0 = gedFile.ReadLine();
          var gedNR = gedFile.Line-1;
          
-         if (/^\s*$/.test(ged$0)) {
              updateReport("empty input-line in "+gedFileName+":"+gedNR+" skipped"); continue gedRead;
          }
          
          var gedThis = new GEDCOM(ged$0,gedNR); 
          
-         if (gedThis.Valid) {
              xmlClosings(gedThis.Level,gedPrev);
          } else {
              updateReport("invalid input-line in "+gedFileName+":"+gedNR+" skipped");
              updateReport("invalid input-line is "+ged$0); continue gedRead;
          }
-         if (gedThis.Level>gedPrev.Level+1) {
              updateReport("invalid level-increment (>1) in "+gedFileName+":"+gedNR+" detected");
          }
-         if (gedThis.Token=="CHAR") {
              encANSEL = (gedThis.Value.toUpperCase()=="ANSEL") ? true : false ;
              updateReport("input-encoding "+gedThis.Value+" in "+gedFileName+":"+gedNR+" detected");
          }
          if (gedThis.Level==0) xmlFile.WriteLine();
          
          switch (gedThis.Token)
-         {
          // -----------------------------------------------------------------
          // if token ~ id, value ~ token [+value(s)?]
          // -----------------------------------------------------------------
              case ("@"+String(gedThis.Id).substr(idPFX.length)+"@") : 
-                 if (/([a-zA-Z_0-9]+)\s+(\S.*)/.test(gedThis.Value)) {
                      xmlFile.Write(tabDepth[gedThis.Level]+"<"+xmlnsPFX+RegExp.$1+gedThis.Id.attr(xmlID)+">"+RegExp.$2); 
                      tagStack[gedThis.Level]="<\/"+xmlnsPFX+RegExp.$1+">"+gedThis.PI;
                  } else {
                      xmlFile.Write(tabDepth[gedThis.Level]+"<"+xmlnsPFX+gedThis.Value+gedThis.Id.attr(xmlID)); 
                      tagStack[gedThis.Level]="<\/"+xmlnsPFX+gedThis.Value+">"+gedThis.PI; gedThis.Value="";
                  }
                  break;
          // -----------------------------------------------------------------
          // enclosing AT-SHARPs mark DATE @#DTOKEN@ date calendar escape; cf. http://homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcch2.htm#DATE_CALENDAR_ESCAPE
          // -----------------------------------------------------------------
              case "DATE" : 
-                 if (!!escDATE && (/@#(D(?:GREGORIAN|JULIAN|HEBREW|FRENCH R|ROMAN|UNKNOWN))@\s+/.test(gedThis.Value))) {
                      xmlFile.Write(tabDepth[gedThis.Level]+"<"+xmlnsPFX+gedThis.Token+(RegExp.$1).attr(escDATE)+">"+RegExp.rightContext); 
                      gedThis.PI=(piSTY && datePI) ? gedPIDATE((RegExp.rightContext).toUpperCase()) : "" ;
                  } else {
                      xmlFile.Write(tabDepth[gedThis.Level]+"<"+xmlnsPFX+gedThis.Token+((gedThis.Value)?">"+gedThis.Value:"")); 
                      gedThis.PI=(gedThis.Value && piSTY && datePI) ? gedPIDATE(gedThis.Value.toUpperCase()) : "" ;
                  }
                  tagStack[gedThis.Level]="<\/"+xmlnsPFX+gedThis.Token+">"+gedThis.PI;
                  break;
          // -----------------------------------------------------------------
          // _UID-check; cf. http://www.tamurajones.net/The_UIDTag.xhtml  http://wiki-de.genealogy.net/UID-Tag
          // -----------------------------------------------------------------
              case "_UID" : 
                  xmlFile.Write(tabDepth[gedThis.Level]+"<"+xmlnsPFX+gedThis.Token+((gedThis.Value)?">"+gedThis.Value:"")); 
                  gedThis.PI=(gedThis.Value && piSTY && _uidPI) ? gedPI_UID(gedThis.Value) : "" ;
                  tagStack[gedThis.Level]="<\/"+xmlnsPFX+gedThis.Token+">"+gedThis.PI;
                  break;
          // -----------------------------------------------------------------
          // enclosing slashes mark /SURN/ surname; check for non-empty value b4!
          // -----------------------------------------------------------------
              case "NAME" : 
                  if (!!surNAME && gedThis.Value) gedThis.Value = gedThis.Value.replace(/\/([^\/]+)\//,"<"+xmlnsPFX+surNAME+">$1<\/"+xmlnsPFX+surNAME+">").replace(/\/\//g,"<"+xmlnsPFX+surNAME+"\/>");
          // -----------------------------------------------------------------
          //
          // -----------------------------------------------------------------
              default : 
                  xmlFile.Write(tabDepth[gedThis.Level]+"<"+xmlnsPFX+gedThis.Token+gedThis.IdRef.attr(xmlIDREF)+((gedThis.Value)?">"+gedThis.Value:"")); 
                  tagStack[gedThis.Level]="<\/"+xmlnsPFX+gedThis.Token+">"+gedThis.PI; 
                  break;
          }
          gedPrev = gedThis; // hold'em
  }
  xmlClosings(0,gedPrev);
  xmlFile.Write("\n<\/"+xmlnsPFX+xmlRoot+">");
  
  // -----------------------------------------------------------------
  // Report + Close + Quit
  // -----------------------------------------------------------------
  
  gedFile.Close();
  xmlFile.Close();
  logFile.WriteLine ( returnReport() ); 
  logFile.Close();
  WScript.Quit(0);
  
  // -----------------------------------------------------------------
  
  </script>
  </job>
  </package>