function parseUri( str )
{
  var   o   = parseUri.options,
        m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
     uri = {},
     i   = 14;

  while (i--) uri[o.key[i]] = m[i] || "";

  uri[o.q.name] = {};
  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
     if ($1) uri[o.q.name][$1] = $2;
  });

  return uri;
};

parseUri.options = {
  strictMode: false,
  key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
  q:   {
     name:   "queryKey",
     parser: /(?:^|&)([^&=]*)=?([^&]*)/g
  },
  parser: {
     strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
     loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
  }
};

function extractURL( k )
{
  return parseUri( document.location.href )[k];
}

/*
//examples
alert( "source : "    + extractURL("source") );
alert( "protocol : "  + extractURL("protocol") );
alert( "authority : " + extractURL("authority") );
alert( "userInfo : "  + extractURL("userInfo") );
alert( "user : "      + extractURL("user") );
alert( "password : "  + extractURL("password") );
alert( "host : "      + extractURL("host") );
alert( "port : "      + extractURL("port") );
alert( "relative : "  + extractURL("relative") );
alert( "path : "      + extractURL("path") );
alert( "directory : " + extractURL("directory") );
alert( "file : "      + extractURL("file") );
alert( "query : "     + extractURL("query") );
alert( "anchor : "    + extractURL("anchor") );
*/

