function $() {
 var elems = new Array();
 for (var i = 0; i < arguments.length; i++) {
  var elem = arguments[i];
  if (typeof elem == 'string') {
   if (document.getElementById)
    elem = document.getElementById(elem);
   else if (document.all)
    elem = document.all[name];
   else if (document.layers)
   	elem = document.layers[name];
  }
  if (arguments.length == 1)
   return elem;
  elems.push(elem);
 }
 return elems;
}
function addLoadEvent(func) {
 var oldonload = window.onload;
 if (typeof window.onload != 'function') window.onload = func;
 else window.onload = function() { oldonload(); func(); }
}
function trim(str) { return str.replace(/^\s*|\s*$/g,""); }
function hasClass(elem, className) { return elem.className.match(new RegExp('(^|\\s)'+className+'($|\\s)')); }
function addClass(elem, className) { if (!hasClass(elem, className)) elem.className = trim(elem.className) + ' ' + className; }
function removeClass(elem, className) { elem.className = trim(elem.className.replace(new RegExp('(.*)(^|\\s)'+className+'($|\\s)(.*)'), '$1$4')); }
function changeClass(elem, className, add) { if (add) addClass(elem, className); else removeClass(elem, className); }
function toggleClass(elem, className) { changeClass(elem, className, !hasClass(elem, className)); }
function getMousePos(e) {
 var pos = new Point(0,0);
 if (e.pageX || e.pageY) 	{
  pos.x = e.pageX;
  pos.y = e.pageY;
 } else if (e.clientX || e.clientY) 	{
  pos.x = e.clientX + document.body.scrollLeft+document.documentElement.scrollLeft;
  pos.y = e.clientY + document.body.scrollTop+document.documentElement.scrollTop;
 }
 return pos;
}
function getPos(obj) {
 var cur = new Point(0, 0);
 if (obj.offsetParent) {
  cur.x = obj.offsetLeft
  cur.y = obj.offsetTop
  while (obj = obj.offsetParent) {
   cur.x += obj.offsetLeft
   cur.y += obj.offsetTop
  }
 }
 return cur;
}
function getTarget(e) {
 var elem;
 if (!e) e = window.event;
 if (!e) return null;
 if (e.target) elem = e.target;
 else if (e.srcElement) elem = e.srcElement;
 if (elem && elem.nodeType == 3) elem = targ.parentNode;
 return elem;
}
var activeMenu = null;
var activeMenuBut = null;
function showMenu(elem, but) {
 if (elem.style.display != 'none') {
  elem.style.display = 'none';
  if (but) removeClass(but, 'down');
  if (activeMenu == elem)
    activeMenuBut = activeMenu = null;
 } else {
  elem.style.display = '';
  if (but) addClass(but, 'down');
  if (activeMenu && activeMenu != elem) {
    activeMenu.style.display = 'none';
    if (activeMenuBut) removeClass(activeMenuBut, 'down');
  }
  activeMenu = elem;
  activeMenuBut = but;
 }
}
function toggleDisplay(elem) {
 if (elem.style.display != 'none') {
  elem.style.display = 'none';
 } else {
  elem.style.display = '';
 }
}
function Point(x, y){
 this.x = x;
 this.y = y;
 this.distance = Point_distance;
 this.difference = Point_difference;
 this.distanceToLineSeg = Point_distanceToLineSeg;
 this.distanceToLine = Point_distanceToLine;
 this.equals = Point_equals;
 this.copy = Point_copy;
 this.toString = Point_toString;
}
function Point_distance() {
 var dx, dy;
 if (arguments.length == 1)      { dx = (this.x-arguments[0].x); dy = (this.y-arguments[0].y); }
 else if (arguments.length == 2) { dx = (this.x-arguments[0]);   dy = (this.y-arguments[1]); }
 return Math.sqrt(dx*dx+dy*dy);
}
function Point_difference(p) {
 if (arguments.length == 1)      return new Point(this.x - arguments[0].x, this.y - arguments[0].y);
 else if (arguments.length == 2) return new Point(this.x - arguments[0], this.y - arguments[1]);
}
function Point_distanceToLineSeg(p1, p2) {
  //Is it a vertical line?
  if (p1.x == p2.x) {
    //Is this between the endpoints?
    if (this.y <= Math.max(p1.y,p2.y) && this.y >= Math.min(p1.y,p2.y))
      //Simply change in x
      return Math.abs(this.x - p1.x);
    //Otherwise its the distance from this to p1 and p2 (the endpoints), return the minimum
    return Math.min(this.distance(p1), this.distance(p2));
  }
  //Is it a horizontal line?
  if (p1.y == p2.y) {
    //Is this between the endpoints?
    if (this.x <= Math.max(p1.x,p2.x) && this.x >= Math.min(p1.x,p2.x))
      //Simply change in y
      return Math.abs(this.y - p1.y);
    //Otherwise its the distance from this to p1 and p2 (the endpoints), return the minimum
    return Math.min(this.distance(p1), this.distance(p2));
  }

  var m = (p2.y-p1.y)/(p2.x-p1.x); //slope of line segment
  var m_ = -1/m; //slope of perpendicular lines
  
  //1) Endpoint 1 boundary:        y=m_*(x-p1.x)+p1.y
  //2) Endpoint 2 boundary:        y=m_*(x-p2.x)+p2.y
  //3) Parallel line through this: y=m*(x-this.x)+this.y
  //4) Line Segment:               y=m*(x-p1.x)+p1.y
  //5) Perpendicular through this: y=m_*(x-this.x)+this.y
  
  //a) 1x3: x = (m*this.x-m_*p1.x+p1.y-this.y)/(m-m_)
  //        y = m_*(x-p1.x)+p1.y
  //b) 2x3: x = (m*this.x-m_*p2.x+p2.y-this.y)/(m-m_)
  //        y = m_*(x-p2.x)+p2.y
  //c) 4x5: x = (m*p1.x-p1.y-m_*this.x+this.y)/(m-m_)
  //        y = m*(x-p1.x)+p1.y

  //First, find a and b, the boundaries for being perpendicular to the line segment
  var a_x = (m*this.x-m_*p1.x+p1.y-this.y)/(m-m_);
  var a_y = m_*(a_x-p1.x)+p1.y
  var b_x = (m*this.x-m_*p2.x+p2.y-this.y)/(m-m_)
  var b_y = m_*(b_x-p2.x)+p2.y
  
  //Is this between a and b?
  if ((this.x <= Math.max(a_x,b_x) && this.x >= Math.min(a_x,b_x)) &&
      (this.y <= Math.max(a_y,b_y) && this.y >= Math.min(a_y,b_y))) {
    //Okay, the distance is the distance perpendicular to the line segment
    //Find c, the point of intersection between the line segment and the perpendicular line through this
    var c_x = (m*p1.x-p1.y-m_*this.x+this.y)/(m-m_);
    var c_y = m*(c_x-p1.x)+p1.y;
    return this.distance(c_x, c_y);
  }
  //Cannot be perpendicular to line segment. Find the distance from this to p1 and p2 (the endpoints), return the minimum
  return Math.min(this.distance(p1), this.distance(p2));
}
function Point_distanceToLine(m, b) {
  var x = (this.x/m+this.y-b)/(m+1/m);
  return this.distance(x, m*x+b);
}
function Point_equals(p) { return this.x == p.x && this.y == p.y; }
function Point_copy() { return new Point(this.x, this.y); }
function Point_toString() { return '('+this.x+','+this.y+')'; }

function Dimension(w, h){
 this.w = w;
 this.h = h;
 this.copy = Dimension_copy;
 this.equals = Dimension_equals;
 this.toString = Dimension_toString;
}
function Dimension_copy() { return new Dimension(this.w, this.h); }
function Dimension_equals(d) { return this.w == d.w && this.h == d.h; }
function Dimension_toString() { return '['+this.w+'x'+this.h+']'; }
function isArray(a) { return a && typeof a === 'object' && typeof a.length === 'number' && !(a.propertyIsEnumerable('length')); }
function copyObject(obj) {
  if (obj == null || !obj) return null;
  var copy;
  if (isArray(obj)) copy = new Array();
  else              copy = new Object();
  for (var param in obj) {
    if (/^(-)?\d+$/.test(param)) {
      var value = obj[param];
      if (typeof value == 'object')
        value = copyObject(value);
      copy[param] = value;
    } else {
      var value = eval('obj.'+param);
      if (typeof value == 'object')
        value = copyObject(value);
      eval('copy.'+param+'=value');
    }
  }
  return copy;
}
var popupCount = 0;
function createPopups() {
 var elems = document.getElementsByTagName('*');
 var total = elems.length;
 for (var i = 0; i < total; i++)
  createPopup(elems[i]);
}
function createPopup(elem) {
 if (typeof elem.title != 'undefined' && elem.title != '') {
  elem.myToolTipEval = /^~/.test(elem.title);
  elem.myToolTip = elem.title.replace(/^~/,'');
  elem.title = '';
  var div = document.createElement('div');
  div.className = 'popup';
  div.style.display = 'none';
  div.id = elem.myToolTipId = 'pop' + popupCount++;
  document.body.appendChild(div);
  elem.onmouseover = showPopup_;
  elem.onmousemove = showPopup_;
  elem.onmouseout = hidePopup_;
 }
}
function showPopup_(e) {
 var posx = 0; var posy = 0;
 if (!e) e = window.event;
 if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; }
 else if (e.clientX || e.clientY) {
  posx = e.clientX + ((document.documentElement&&document.documentElement.scrollLeft)?document.documentElement.scrollLeft:document.body.scrollLeft);
  posy = e.clientY + ((document.documentElement&&document.documentElement.scrollTop)?document.documentElement.scrollTop:document.body.scrollTop);
 }
 try {
  var div = $(this.myToolTipId);
  if (this.tagName == 'INPUT' && this.type == 'text') { posx+=6; posy+=6; }
  else { posx+=10; posy+=10; }
  div.style.left = posx + 'px';
  div.style.top = posy + 'px';
  div.style.display = 'block';
  div.innerHTML = (this.myToolTipEval)?eval(this.myToolTip):this.myToolTip;
 } catch (ex) {}
}
function hidePopup(elem) {
 try { if (/^pop\d+$/.test(elem.myToolTipId)) $(elem.myToolTipId).style.display = 'none'; } catch (ex) {}
}
function hidePopup_(e) {
 try { if (/^pop\d+$/.test(this.myToolTipId)) $(this.myToolTipId).style.display = 'none'; } catch (ex) {}
}
