//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006-2007 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
var MooTools = {version : "1.11"};

/* -----------------------------------------------------------------------------------------------*/
/*                            Core                                                                */
/* -----------------------------------------------------------------------------------------------*/

function $defined(A)
{
  return (A != undefined);
}

function $type(B)
{
  if (!$defined(B))
  {
    return false;
  }
  
  if (B.htmlElement)
  {
    return"element";
  }
  
  var A = typeof B;
  if (A == "object" && B.nodeName)
  {
    switch (B.nodeType)
    {
      case 1:
        return "element";
      case 3: 
        return (/\S/).test(B.nodeValue) ? "textnode" : "whitespace";
    }
  }
  
  if (A == "object" || A == "function")
  {
    switch (B.constructor)
    {
      case Array :  return "array";
      case RegExp : return "regexp";
      case Class :  return "class";
    }
    
    if (typeof B.length == "number")
    {
      if (B.item)
      {
        return "collection";
      }
      
      if (B.callee)
      {
        return "arguments";
      }
    }
  }
  return A;
}

function $merge()
{
  var C = {};
  for (var B = 0; B < arguments.length; B++)
  {
    for (var E in arguments[B])
    {
      var A = arguments[B][E];
      var D = C[E];
      
      if (D && $type(A) == "object" && $type(D) == "object")
      {
        C[E] = $merge(D, A);
      }
      else
      {
        C[E] = A;
      }
    }
  }
  return C;
}

var $extend = function()
{
  var A = arguments;
  if (!A[1])
  {
    A = [this, A[0]];
  }
  for (var B in A[1])
  {
    A[0][B] = A[1][B];
  }
  return A[0];
};

var $native = function()
{
  for (var B = 0, A = arguments.length; B < A; B++)
  {
    arguments[B].extend = function(C)
    {
      for (var D in C)
      {
        if (!this.prototype[D])
        {
          this.prototype[D] = C[D];
        }
        
        if (!this[D])
        {
          this[D]=$native.generic(D);
        }
      }
    };
  }
};

$native.generic = function(A)
{
  return function(B) {return this.prototype[A].apply(B, Array.prototype.slice.call(arguments, 1));};
};

$native (Function, Array, String, Number);

function $chk(A) 
{ 
  return !!(A||A===0);
}

function $pick(B, A)
{
  return $defined(B) ? B : A;
}

function $random(B, A)
{
  return Math.floor(Math.random() * (A - B + 1) + B);
}

function $time()
{
  return new Date().getTime();
}

function $clear(A)
{
  clearTimeout(A);
  clearInterval(A);
  return null;
}

var Abstract = function(A)
{
  A = A || {};
  A.extend = $extend;
  return A;
};

var Window = new Abstract(window);

var Document = new Abstract(document);

document.head = document.getElementsByTagName("head")[0];

window.xpath = !!(document.evaluate);

if (window.ActiveXObject)
{
  window.ie = window[window.XMLHttpRequest ? "ie7" : "ie6"] = true;
}
else
{
  if (document.childNodes && !document.all && !navigator.taintEnabled)
  {
    window.webkit = window[window.xpath ? "webkit420" : "webkit419"] = true;
  }
  else
  {
    if (document.getBoxObjectFor != null)
    {
      window.gecko=true;
    }
  }
}
window.khtml = window.webkit;

Object.extend = $extend;

if (typeof HTMLElement == "undefined")
{
  var HTMLElement = function(){};
  if (window.webkit) 
  {
    document.createElement("iframe");
  }
  HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {};
}

HTMLElement.prototype.htmlElement = function(){};

if (window.ie6) 
{
  try
  {
    document.execCommand("BackgroundImageCache", false, true);
  } 
  catch (e) {}
}

/* -----------------------------------------------------------------------------------------------*/
/*                            Class                                                               */
/* -----------------------------------------------------------------------------------------------*/

var Class = function(B)
{
  var A = function()
  {
    return (arguments[0] !== null && this.initialize && $type(this.initialize) == "function") ? this.initialize.apply(this,arguments) : this;
  };
  
  $extend(A, this);
  
  A.prototype = B;
  
  A.constructor = Class;
  
  return A;
};

Class.empty = function(){};

Class.prototype = 
{
  extend: function(B)
  {
    var C = new this(null);
    for (var D in B)
    {
      var A = C[D];
      C[D] = Class.Merge(A, B[D]);
    }
    
    return new Class(C);
  },
  
  implement: function()
  {
    for (var B = 0, A = arguments.length; B < A; B++)
    {
      $extend(this.prototype, arguments[B]);
    }
  }
};

Class.Merge = function(C, D)
{
  if (C && C != D)
  {
    var B = $type(D);
    if (B != $type(C))
    {
      return D;
    }
    switch (B)
    {
      case "function":
        var A = function()
        {
          this.parent = arguments.callee.parent;
          return D.apply(this, arguments);
        };
        A.parent = C;
        return A;
      case "object":
        return $merge(C, D);
    }
  }
  return D;
};

/* -----------------------------------------------------------------------------------------------*/
/*                            Native - Function                                                   */
/* -----------------------------------------------------------------------------------------------*/

Function.extend({
  create: function(A)
  {
    var B = this;
    A = $merge({
      bind: B,
      event: false,
      "arguments":  null,
      delay: false,
      periodical: false,
      attempt: false}, A);
      
    if ($chk(A.arguments) && $type(A.arguments) != "array")
    {
      A.arguments = [A.arguments];
    }
    
    return function (E)
    {
      var C;
      if (A.event)
      {
        E = E || window.event;
        C = [(A.event === true) ? E : new A.event(E)];
        if (A.arguments)
        {
          C.extend(A.arguments);
        }
      }
      else
      {
        C = A.arguments || arguments;
      }
      
      var F = function()
      {
        return B.apply($pick(A.bind, B), C);
      };
      
      if (A.delay)
      {
        return setTimeout(F, A.delay);
      }
      
      if (A.periodical)
      {
        return setInterval(F, A.periodical);
      }
      
      if (A.attempt)
      {
        try
        {
          return F();
        }
        catch(D)
        {
          return false;
        }
      }
      
      return F();
    };
  },
  
  pass: function(A, B)
  {
    return this.create({"arguments":  A, bind: B});
  },
  
  attempt: function(A, B)
  {
    return this.create({"arguments":  A, bind: B, attempt:true})();
  },
  
  bind: function(B, A)
  {
    return this.create({bind : B, "arguments":  A});
  },
  
  bindAsEventListener: function(B, A)
  {
    return this.create({bind : B, event : true, "arguments":  A});
  },
  
  delay: function(B, C, A)
  {
    return this.create({delay : B, bind : C, "arguments":  A})();
  },
  
  periodical: function(A, C, B)
  {
    return this.create({periodical : A, bind : C, "arguments":  B})();
  }
});

