/**
 * xmlDate is a variation of the native javascript Date object, which can be use
 * to handle <a href="http://www.ietf.org/rfc/rfc3339.txt">RFC3339</a>,
 * <a href="http://www.w3.org/TR/NOTE-datetime">W3C datetime</a> or
 * a subset of ISO8601.
 *
 * xmlDate can also have a given timezoneOffset, which overrides the default timezoneOffset.
 * 
 * xmlDate also implements a tz database parser and resolver based on
 * <a href="ftp://elsie.nci.nih.gov/pub/">Olson's tz database</a>, see also
 * <a href="http://www.twinsun.com/tz/tz-link.htm">Sources for Time Zone and Daylight Saving Time Data</a>.
 * 
 * Copyright (C) 2006 Philippe GOETZ
 * Author: Philippe GOETZ mailto:philippe.goetz@wanadoo.fr
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 *
 * Differences between xmlDate and <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date">Date (Javascript 1.5)</a>
 * - new xmlDate(dateString) - dateString is a xmlDate string
 * - new xmlDate(yr_num, mo_num, day_num[, hr_num[, min_num[, sec_num[, ms_num]]]]) NOT IMPLEMENTED
 * 
 * - valueOf() - same as getTime()
 * - toSource() - (new xmlDate(...)) instead (new Date(...)) => Object.toSource() not supported by IE
 * - toString() - same as toLocaleString()
 *
 * - Date.UTC(year, month, date[, hrs[, min[, sec[, ms]]]) NOT IMPLEMENTED
 * - parse(dateString) - dateString is a xmlDate string
 * - toUTCString() - return a xmlDate UTC string (Z)
 * - toGMTString() NOT IMPLEMENTED
 * - setTimezone(timezoneOffset) - indicates the timezoneOffset to be used
 * - getYear() NOT IMPLEMENTED
 * - setYear() NOT IMPLEMENTED
 * - setFullYear() NOT IMPLEMENTED
 * - setMonth() NOT IMPLEMENTED
 * - setDate() NOT IMPLEMENTED
 * - setHours() NOT IMPLEMENTED
 * - setMinutes() NOT IMPLEMENTED
 * - setSeconds() NOT IMPLEMENTED
 * - setMilliseconds() NOT IMPLEMENTED
 * - toLocaleString() - return a xmlDate string with timezone, if applicable
 * - toLocaleDateString() NOT IMPLEMENTED
 * - toLocaleTimeString() NOT IMPLEMENTED
 *
 * tz database in xmlDate
 * setTimezone(timezoneOffset) indicates the offset of the timezone to be used. By default, the Date object timezoneOffset is used.
 * setTimezone(timezoneString) indicates the timezone to be used and (partially or fully) parse the tz database.
 * getTimezoneOffset([true]) returns the timezoneoffset evaluated from the parsed tz database or when true, returns the timezone code.
 */

/**
 * <h2>Constructor</h2>
 * - new Date()
 * - new Date(milliseconds)
 * - new Date(dateString)
 */
var xmlDate = function(arg) {
  if(typeof(arg)=="string") {
    arg = this.parse(arg);
  }
  this.date = arg==undefined ? new Date() : new Date(arg);
  return this;
}
/**
 * <h2>Object methods</h2>
 * - valueOf()
 * - toSource()
 * - toString()
 */
xmlDate.prototype.valueOf = function() {
  return this.date.valueOf();
}
xmlDate.prototype.toSource = function() {
  return "(new xmlDate("+this.date.getTime()+"))";
}
xmlDate.prototype.toString = function() {
  return this.toLocaleString();
}
/**
 * <h2>UTC related properties and methods</h2>
 * - date - underlying javascript Date object
 * - parse(dateString) - dateString is a xmlDate string
 * - getTime()
 * - setTime(timeValue)
 * - getUTCFullYear(yearValue[, monthValue[, dayValue]])
 * - getUTCMonth(monthValue[, dayValue])
 * - getUTCDate(dayValue)
 * - getUTCHours(hoursValue[, minutesValue[, secondsValue[, msValue]]])
 * - getUTCMinutes(minutesValue[, secondsValue[, msValue]])
 * - getUTCSeconds(secondsValue[, msValue])
 * - getUTCMilliseconds(msValue)
 * - getUTCDay()
 * - setUTCFullYear()
 * - setUTCMonth()
 * - setUTCDate()
 * - setUTCHours()
 * - setUTCMinutes()
 * - setUTCSeconds()
 * - setUTCMilliseconds()
 * - toUTCString() - return a xmlDate UTC string (Z)
 */
xmlDate.prototype.parse = function(dateString) {
  //TO BE FULLY ISO8601 /(\d\d\d\d(?:-)?\d\d(?:-)?\d\d)?(?:T(\d\d(?::)\d\d(?::)\d\d)(\.\d{0,3})?)?([Z+-](?:\d\d(?::)\d\d)?)?/.exec(dateString);
  var g = /(\d\d\d\d-\d\d-\d\d)(?:T(\d\d:\d\d:\d\d)(\.\d{0,3})?)?(Z|(?:[+-]\d\d\d\d))?/.exec(dateString);
  //if(g[1]==undefined) g[1]="";
  g[1] = g[1].replace(/-/g,"");
  if(g[2]==undefined) g[2]="";
  g[2] = g[2].replace(/:/g,"");
  if(g[3]==undefined) g[3]="";
  g[3] = g[3].replace(/\./g,"");
  var YYYY = parseInt(g[1].substr(0,4));
  var MM = parseInt("1"+g[1].substr(4,2))%100;
  var DD = parseInt("1"+g[1].substr(6,2))%100;
  var hh = parseInt("1"+g[2].substr(0,2))%100;
  var mm = parseInt("1"+g[2].substr(2,2))%100;
  var ss = parseInt("1"+g[2].substr(4,2))%100;
  var ms = parseInt("1"+(g[3]+"000").substr(0,3))%1000;
  var d = Date.UTC(YYYY,MM-1,DD,hh,mm,ss,ms);
  if(g[4]!="Z") {
    var hh = parseInt("1"+g[4].substr(1,2))%100;
    var mm = parseInt("1"+g[4].substr(3,2))%100;
    var tz = parseInt(g[4].substr(0,1)+"1")*(hh*60+mm)
    if(this.timezone==undefined) this.timezone=-tz
    d -= tz*60*1000;
  }
  return d;
}
xmlDate.prototype.getTime = function() {
  return this.date.getTime();
}
xmlDate.prototype.setTime = function(timeValue) {
  this.date.setTime(timeValue);
}
xmlDate.prototype.getUTCFullYear = function() {
  return this.date.getUTCFullYear();
}
xmlDate.prototype.getUTCMonth = function() {
  return this.date.getUTCMonth();
}
xmlDate.prototype.getUTCDate = function() {
  return this.date.getUTCDate();
}
xmlDate.prototype.getUTCHours = function() {
  return this.date.getUTCHours();
}
xmlDate.prototype.getUTCMinutes = function() {
  return this.date.getUTCMinutes();
}
xmlDate.prototype.getUTCSeconds = function() {
  return this.date.getUTCSeconds();
}
xmlDate.prototype.getUTCMilliseconds = function() {
  return this.date.getUTCMilliseconds();
}
xmlDate.prototype.getUTCDay = function() {
return this.date.getUTCDay();
}
xmlDate.prototype.setUTCFullYear = function(yearValue, monthValue, dayValue) {
  if(dayValue!=undefined) this.date.setUTCFullYear(yearValue, monthValue, dayValue);
  else if(monthValue!=undefined) this.date.setUTCFullYear(yearValue, monthValue);
  else this.date.setUTCFullYear(yearValue);
}
xmlDate.prototype.setUTCMonth = function(monthValue, dayValue) {
  if(dayValue!=undefined) this.date.setUTCMonth(monthValue, dayValue);
  else this.date.setUTCMonth(monthValue);
}
xmlDate.prototype.setUTCDate = function(dayValue) {
  this.date.setUTCDate(dayValue);
}
xmlDate.prototype.setUTCHours = function(hoursValue, minutesValue, secondsValue, msValue) {
  if(msValue!=undefined) this.date.setUTCHours(hoursValue, minutesValue, secondsValue, msValue);
  else if(secondsValue!=undefined) this.date.setUTCHours(hoursValue, minutesValue, secondsValue);
  else if(minutesValue!=undefined) this.date.setUTCHours(hoursValue, minutesValue);
  else this.date.setUTCHours(hoursValue);
}
xmlDate.prototype.setUTCMinutes = function(minutesValue, secondsValue, msValue) {
  if(msValue!=undefined) this.date.setUTCMinutes(minutesValue, secondsValue, msValue);
  else if(secondsValue!=undefined) this.date.setUTCMinutes(minutesValue, secondsValue);
  else this.date.setUTCMinutes(minutesValue);
}
xmlDate.prototype.setUTCSeconds = function(secondsValue, msValue) {
  if(msValue!=undefined) this.date.setUTCSeconds(secondsValue, msValue);
  else this.date.setUTCSeconds(secondsValue);
}
xmlDate.prototype.setUTCMilliseconds = function(millisecondsValue) {
  this.date.setUTCMilliseconds(millisecondsValue);
}
xmlDate.prototype.toUTCString = function() {
  var str = (10000+this.date.getUTCFullYear()).toString().substr(1,4) +
        "-"+(101+this.date.getUTCMonth()).toString().substr(1,2) +
        "-"+(100+this.date.getUTCDate()).toString().substr(1,2) +
        "T"+(100+this.date.getUTCHours()).toString().substr(1,2) +
        ":"+(100+this.date.getUTCMinutes()).toString().substr(1,2) +
        ":"+(100+this.date.getUTCSeconds()).toString().substr(1,2);
  var ms=(1000+this.date.getUTCMilliseconds()).toString().substr(1,3);
  ms = /(\d*[1-9])/.exec(ms);
  if(ms!=null) str += "."+ms[1];
  str += "Z";
  return str;
}

/**
 * <h2>Locale related properties and methods</h2>
 * - files - url where to get the tz directory (replaced by a lookup object after successful reading)
 *      The directory file is a text file, in which each line contains the (unique) main name of the zone and its related files
 * - rulesLookup - internal rules lookup object
 * - zonesLookup - internal zones lookup object
 * - timezone - copy of the last timezone set (either an offset or a zone)
 * - setTimezone(timezone) - timezone either an offset or a zone
 *      If the zone is unkonwn,
 *        1. the directory will be read, if not already proceeded
 *        2. the main file will be read and proceeded
 *        3. if the zone remains unknown, all the other files will be read and proceeded
 *        The parsing will fill the rulesLookup and zonesLookup
 * - getTimezoneOffset()
 *      The timezoneOffset will be computed using the timezone.
 *      If the timezone is a string, the lookups will be used to determine the offset.
 * - getTimezoneOffset(true)
 *      Instead returning the offset in minutes, the function returns the timezone code (e.g. CET or CEST for Paris).
 * - getFullYear()
 * - getMonth()
 * - getDate()
 * - getHours()
 * - getMinutes()
 * - getSeconds()
 * - getMilliseconds()
 * - getDay()
 * - toLocaleString()
 */
xmlDate.prototype.files = "tz/dir.txt";
xmlDate.prototype.rulesLookup = new Object();
xmlDate.prototype.zonesLookup = new Object();
xmlDate.prototype.setTimezone = function(timezone) {
  this.timezone = timezone;
  if(typeof(timezone)=="number") return;
  if(xmlDate.prototype.zonesLookup[timezone]!=undefined) return;
  if(typeof(xmlDate.prototype.files)=="string") {
    var xmlRequest = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    xmlRequest.open("GET",xmlDate.prototype.files,false);
    xmlRequest.send(null);
    xmlDate.prototype.files = new Array();
    var files = xmlRequest.responseText.split("\n");
    for(var f in files) {
      var file = files[f]
      file=/(\S*)\s*(\S*)/.exec(file);
      if(file==null) continue;
      xmlDate.prototype.files[file[1].toLowerCase()]=file[2];
    }
  }

  function processFile(str) {
    var zone = null;
    var lines = str.split("\n");
    for(var l in lines) {
      var line = lines[l];
      line = line.split("#")[0];
      if(line.length<4) continue;
      if(/^\s/.exec(line)) line = "Zone "+zone+line;
      line = line.split(/\s+/);
      var t = line.shift();
      switch(t) {
        case "Rule":
          var rule = line.shift();
          if(xmlDate.prototype.rulesLookup[rule]==undefined) xmlDate.prototype.rulesLookup[rule]=new Array();
          xmlDate.prototype.rulesLookup[rule].push(line);
          //if(window.rule==undefined) window.rule=1; else window.rule++;
          break;
        case "Zone":
          zone = line.shift();
          if(xmlDate.prototype.zonesLookup[zone]==undefined) xmlDate.prototype.zonesLookup[zone]=new Array();
          xmlDate.prototype.zonesLookup[zone].push(line);
          //if(window.zone==undefined) window.zone=1; else window.zone++;
          break;
        case "Link":
          if(xmlDate.prototype.zonesLookup[line[1]]!=undefined) throw "Error: Link override Zone "+line[1];
          xmlDate.prototype.zonesLookup[line[1]] = line[0];
          break;
        case "Leap": break;
        default:
          throw "Error: Parsing zone "+lines; // [l];
      }
    }
  }

  var url = xmlDate.prototype.files[timezone.split("/")[0].toLowerCase()];
  if(url!=undefined) {
    delete xmlDate.prototype.files[timezone.split("/")[0].toLowerCase()];
    var xmlRequest = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    xmlRequest.open("GET",url,false);
    xmlRequest.send(null);
    processFile(xmlRequest.responseText);
    if(xmlDate.prototype.zonesLookup[timezone]!=undefined) return;
  }
  for(var f in xmlDate.prototype.files) {
    var url = xmlDate.prototype.files[f];
    if(url=="") continue;
    var xmlRequest = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    xmlRequest.open("GET",url,false);
    xmlRequest.send(null);
    processFile(xmlRequest.responseText);
  }
  xmlDate.prototype.files = new Array();
}
xmlDate.prototype.getTimezoneOffset = function(b) {
  if(this.timezone==undefined) return this.date.getTimezoneOffset();
  if(typeof(this.timezone)=="number") return this.timezone;

  function parseTime(str) {
    var g = /(-?\d*)(?::0*(\d*))?(?::0*(\d*))?([wsugz])?$/.exec(str);
    g[1] = parseInt(g[1]);
    g[2] = ((g[2]==undefined)||(g[2]=="")) ? 0 : parseInt(g[2]);
    g[3] = ((g[3]==undefined)||(g[3]=="")) ? 0 : parseInt(g[3]);
	
    // TODO: g[4] ??? w=TIME_WALL, s=TIME_STANDARD, u|g|z=TIME_UNIVERSAL
	switch (g[4]) {
		case 'w': ;
		case 's': break;
		default: g[4] = 'u'; break;
	}
	
    return g;
  }
  
  function buildToFromDate(by,bm,bd,bt,br) {
	var ret = null;
    var bmonth = {"jan":0,"feb":1,"mar":2,"apr":3,"may":4,"jun":5,"jul":6,"aug":7,"sep":8,"oct":9,"nov":10,"dec":11}[bm.substr(0,3).toLowerCase()];
    var bday = parseInt(bd);

    if(bday.toString()=="NaN") {
		
      if(bd.substr(0,4)=="last") {
        var bday = {"sun":0,"mon":1,"tue":2,"wed":3,"thu":4,"fri":5,"sat":6}[bd.substr(4,3).toLowerCase()];
        var g = parseTime(bt);
        ret = new Date(Date.UTC(by,bmonth+1,1,g[1]-24,g[2],g[3]));
        ret.setUTCHours(ret.getUTCHours()-24*((7-bday+ret.getUTCDay())%7));
      
	  } else {
        var bday = {"sun":0,"mon":1,"tue":2,"wed":3,"thu":4,"fri":5,"sat":6}[bd.substr(0,3).toLowerCase()];
        if(bday!=undefined) {
			
          if(bd.substr(3,2)==">=") {
            var g = parseTime(bt);
            ret = new Date(Date.UTC(by,bmonth,bday,g[1],g[2],g[3]));
            ret.setUTCHours(ret.getUTCHours()+24*((7+bday-ret.getUTCDay())%7));
			
          } else if(bd.substr(3,2)=="<=") {
            var g = parseTime(bt);
            ret = new Date(Date.UTC(by,bmonth,bday,g[1],g[2],g[3]));
            ret.setUTCHours(ret.getUTCHours()-24*((7-bday+ret.getUTCDay())%7));
			
          } else {
            throw "Error: Parsing rule "+rules[br];
          }
		  
        } else {
          throw "Error: Parsing rule "+rules[br];
        }
      }
	  
    } else {
      var g = parseTime(bt);
      ret = new Date(Date.UTC(by,bmonth,bday,g[1],g[2],g[3]));
      ret.setUTCHours(ret.getUTCHours()-24*((7-bday+ret.getUTCDay())%7));
    }

	return ret;
  }
  
  var timezone = this.timezone;
  var zones = xmlDate.prototype.zonesLookup[timezone];
  
  // 1. Process link
  if(zones==undefined) throw "Error: Unknown timezone "+timezone;
  while(typeof(zones)=="string") {
    timezone = zones;
    zones = xmlDate.prototype.zonesLookup[timezone];
    if(zones==undefined) throw "Error: Unknown timezone "+timezone;
  }
  
  // 2. Search the matching entry in zones
  for(var z=0; z<zones.length; z++) {
    var zone = zones[z];
    if(!zone[3]) break; // stop if there is no end year
    var YYYY = parseInt(zone[3]);
    var MM = 11;
    var DD = 31;
    if(zone[4]) {
      MM = {"jan":0,"feb":1,"mar":2,"apr":3,"may":4,"jun":5,"jul":6,"aug":7,"sep":8,"oct":9,"nov":10,"dec":11}[zone[4].substr(0,3).toLowerCase()];
      DD = parseInt(zone[5]);
    }
    var t = parseTime(zone[6] ? zone[6] : "23:59:59");
    var d = Date.UTC(YYYY,MM,DD,t[1],t[2],t[3]);
    if(this.date.getTime()<d) break;
  }
  if(z==zones.length) throw "Warning: No DST for "+timezone;
  var zone = zones[z];
  var gmtoff = parseTime(zone[0]);
  gmtoff[0] = gmtoff[1] < 0 ? -1 : 1; 
  gmtoff[1] = Math.abs(gmtoff[1]);
  gmtoff = gmtoff[0]*(((gmtoff[1]*60+gmtoff[2])*60+gmtoff[3])*1000);
  
  var year = this.date.getUTCFullYear();
  var dmonth= {0:"jan",1:"feb",2:"mar",3:"apr",4:"may",5:"jun",6:"jul",7:"aug",8:"sep",9:"oct",10:"nov",11:"dec"}[this.date.getUTCMonth()];
  var dday  = {0:"sun",1:"mon",2:"tue",3:"wed",4:"thu",5:"fri",6:"sat"}[this.date.getUTCDay()];

var gmtsave = null;
  var gmtdate = 0;
  var rules = xmlDate.prototype.rulesLookup[zone[1]];
  var d = 0;
  
  for(var r in rules) {
	rule = rules[r];
	
	// rule[0] from year, rule[1] to year, rule[2] type, rule[3] in, rule[4] on, rule[5] at, rule[6] save, rule[7] letter
	if (typeof(rule[1])!="number") {
		switch (rule[1].toString().toLowerCase()){
			case "only": rule[1]=rule[0]; break;
			case "max": rule[1]=9999; break;  // a very large number, this script will be gone long before then ...
		}
	}
	
	if ((year<rule[0])||(year>rule[1])) continue;
    if (rule[1]=="only"){
	  rule[1]=rule[0];
	}
	
    // TODO: rule[2] RULE_TYPE ???
    var month = {"jan":0,"feb":1,"mar":2,"apr":3,"may":4,"jun":5,"jul":6,"aug":7,"sep":8,"oct":9,"nov":10,"dec":11}[rule[3].substr(0,3).toLowerCase()];
    var day = parseInt(rule[4]);
	var yr = this.getUTCFullYear(); // Get the current year to replace in the rule
	
	var ruleStr=""
	for(var k=0; k<rule.length; k++){
		ruleStr+=rule[k]+"¤";
	}
	
	// Check that the requested time is between the begin and end dates of the rule, if so then
	// hold the requested time start time for comparison with other possible overriding rules .. 
	var dBegin = buildToFromDate( rule[0], rule[3], rule[4], rule[5], r);
	  
	if (this.date >= dBegin)  {
		// so this rule applies 
		var dEnd = buildToFromDate( rule[1], rule[3], rule[4], rule[5], r);
		
		// make the threshold date for the requested year accroding to this rule
		if (this.date <= dEnd) {
			d = buildToFromDate( year, rule[3], rule[4], rule[5], r );
		} else {
			d = dEnd;
		}

		if ((d > gmtdate) && (this.date > d)){
			// Either - No previous rule has matched so just use this one ..
			// Or - We already have a rule that this time fits so need to test to see if the new rule is
			// more recent and the requested date is after the rule, compare this date with the new rules start date and take the later of 
			// the 2
			gmtdate=d;
			gmtsave=rule;
		} 
		
	}
  }
  
  if(b) {
    var s = (gmtsave!=null)&&(gmtsave[7]!="-") ? gmtsave[7] : "";
    var z = zone[2].split("/");
    if(z.length>1) return z[s=="" ? 0 : 1];
    return z[0].replace("%s",s);
  }
  
  var gmtnull=gmtsave==null;
  if(gmtsave!=null) {
	gmtsave = parseTime(gmtsave[6]);
    gmtsave[0] = gmtsave[1] < 0 ? -1 : 1; gmtsave[1] = Math.abs(gmtsave[1]);
    gmtsave = gmtsave[0]*(((gmtsave[1]*60+gmtsave[2])*60+gmtsave[3])*1000);
  } else {
    gmtsave = 0;
  }
  
  return -Math.ceil((gmtoff+gmtsave)/60/1000);
}
xmlDate.prototype.localeDate = function() {
  var date = new xmlDate(this.date.getTime());
  date.setTimezone(this.timezone);
  date.setUTCMinutes(date.getUTCMinutes()-date.getTimezoneOffset());
  return date;
}
xmlDate.prototype.getFullYear = function() {
  var date = this.localeDate();
  return date.getUTCFullYear();
}
xmlDate.prototype.getMonth = function() {
  var date = this.localeDate();
  return date.getUTCMonth();
}
xmlDate.prototype.getDate = function() {
  var date = this.localeDate();
  return date.getUTCDate();
}
xmlDate.prototype.getHours = function() {
  var date = this.localeDate();
  return date.getUTCHours();
}
xmlDate.prototype.getMinutes = function() {
  var date = this.localeDate();
  return date.getUTCMinutes();
}
xmlDate.prototype.getSeconds = function() {
  var date = this.localeDate();
  return date.getUTCSeconds();
}
xmlDate.prototype.getMilliseconds = function() {
  var date = this.localeDate();
  return date.getUTCMilliseconds();
}
xmlDate.prototype.getDay = function() {
  var date = this.localeDate();
  return date.getUTCDay();
}
xmlDate.prototype.toLocaleString = function() {
  var date = new xmlDate(this.date.getTime());
  if(this.timezone) date.setTimezone(this.timezone);
  var timezone = -this.getTimezoneOffset();
  date.setUTCMinutes(date.getUTCMinutes()+timezone);
  var str = date.toUTCString();
  if(timezone==0) return str;
  var tz = timezone<0 ? "-" : "+";
  tz += (100+Math.ceil(Math.abs(timezone)/60)).toString().substr(1,2);
  tz += (100+(Math.abs(timezone)%60)).toString().substr(1,2);
  return str.replace("Z",tz);
}
xmlDate.prototype.toLocaleTimeString = function() {
	var str=toLocaleString();
	
	str=str.slice(16);
	
	return str;
}

