2fc7b2574a056688658a7f09d235277d.json 70.3 KB
{"ast":null,"code":"// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n'use strict';\n\nvar punycode = require('punycode');\n\nvar util = require('./util');\n\nexports.parse = urlParse;\nexports.resolve = urlResolve;\nexports.resolveObject = urlResolveObject;\nexports.format = urlFormat;\nexports.Url = Url;\n\nfunction Url() {\n  this.protocol = null;\n  this.slashes = null;\n  this.auth = null;\n  this.host = null;\n  this.port = null;\n  this.hostname = null;\n  this.hash = null;\n  this.search = null;\n  this.query = null;\n  this.pathname = null;\n  this.path = null;\n  this.href = null;\n} // Reference: RFC 3986, RFC 1808, RFC 2396\n// define these here so at least they only have to be\n// compiled once on the first module load.\n\n\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n    portPattern = /:[0-9]*$/,\n    // Special case for a simple path URL\nsimplePathPattern = /^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,\n    // RFC 2396: characters reserved for delimiting URLs.\n// We actually just auto-escape these.\ndelims = ['<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t'],\n    // RFC 2396: characters not allowed for various reasons.\nunwise = ['{', '}', '|', '\\\\', '^', '`'].concat(delims),\n    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.\nautoEscape = ['\\''].concat(unwise),\n    // Characters that are never ever allowed in a hostname.\n// Note that any invalid chars are also handled, but these\n// are the ones that are *expected* to be seen, so we fast-path\n// them.\nnonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),\n    hostEndingChars = ['/', '?', '#'],\n    hostnameMaxLen = 255,\n    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,\n    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,\n    // protocols that can allow \"unsafe\" and \"unwise\" chars.\nunsafeProtocol = {\n  'javascript': true,\n  'javascript:': true\n},\n    // protocols that never have a hostname.\nhostlessProtocol = {\n  'javascript': true,\n  'javascript:': true\n},\n    // protocols that always contain a // bit.\nslashedProtocol = {\n  'http': true,\n  'https': true,\n  'ftp': true,\n  'gopher': true,\n  'file': true,\n  'http:': true,\n  'https:': true,\n  'ftp:': true,\n  'gopher:': true,\n  'file:': true\n},\n    querystring = require('querystring');\n\nfunction urlParse(url, parseQueryString, slashesDenoteHost) {\n  if (url && util.isObject(url) && url instanceof Url) return url;\n  var u = new Url();\n  u.parse(url, parseQueryString, slashesDenoteHost);\n  return u;\n}\n\nUrl.prototype.parse = function (url, parseQueryString, slashesDenoteHost) {\n  if (!util.isString(url)) {\n    throw new TypeError(\"Parameter 'url' must be a string, not \" + typeof url);\n  } // Copy chrome, IE, opera backslash-handling behavior.\n  // Back slashes before the query string get converted to forward slashes\n  // See: https://code.google.com/p/chromium/issues/detail?id=25916\n\n\n  var queryIndex = url.indexOf('?'),\n      splitter = queryIndex !== -1 && queryIndex < url.indexOf('#') ? '?' : '#',\n      uSplit = url.split(splitter),\n      slashRegex = /\\\\/g;\n  uSplit[0] = uSplit[0].replace(slashRegex, '/');\n  url = uSplit.join(splitter);\n  var rest = url; // trim before proceeding.\n  // This is to support parse stuff like \"  http://foo.com  \\n\"\n\n  rest = rest.trim();\n\n  if (!slashesDenoteHost && url.split('#').length === 1) {\n    // Try fast path regexp\n    var simplePath = simplePathPattern.exec(rest);\n\n    if (simplePath) {\n      this.path = rest;\n      this.href = rest;\n      this.pathname = simplePath[1];\n\n      if (simplePath[2]) {\n        this.search = simplePath[2];\n\n        if (parseQueryString) {\n          this.query = querystring.parse(this.search.substr(1));\n        } else {\n          this.query = this.search.substr(1);\n        }\n      } else if (parseQueryString) {\n        this.search = '';\n        this.query = {};\n      }\n\n      return this;\n    }\n  }\n\n  var proto = protocolPattern.exec(rest);\n\n  if (proto) {\n    proto = proto[0];\n    var lowerProto = proto.toLowerCase();\n    this.protocol = lowerProto;\n    rest = rest.substr(proto.length);\n  } // figure out if it's got a host\n  // user@server is *always* interpreted as a hostname, and url\n  // resolution will treat //foo/bar as host=foo,path=bar because that's\n  // how the browser resolves relative URLs.\n\n\n  if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n    var slashes = rest.substr(0, 2) === '//';\n\n    if (slashes && !(proto && hostlessProtocol[proto])) {\n      rest = rest.substr(2);\n      this.slashes = true;\n    }\n  }\n\n  if (!hostlessProtocol[proto] && (slashes || proto && !slashedProtocol[proto])) {\n    // there's a hostname.\n    // the first instance of /, ?, ;, or # ends the host.\n    //\n    // If there is an @ in the hostname, then non-host chars *are* allowed\n    // to the left of the last @ sign, unless some host-ending character\n    // comes *before* the @-sign.\n    // URLs are obnoxious.\n    //\n    // ex:\n    // http://a@b@c/ => user:a@b host:c\n    // http://a@b?@c => user:a host:c path:/?@c\n    // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n    // Review our test case against browsers more comprehensively.\n    // find the first instance of any hostEndingChars\n    var hostEnd = -1;\n\n    for (var i = 0; i < hostEndingChars.length; i++) {\n      var hec = rest.indexOf(hostEndingChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec;\n    } // at this point, either we have an explicit point where the\n    // auth portion cannot go past, or the last @ char is the decider.\n\n\n    var auth, atSign;\n\n    if (hostEnd === -1) {\n      // atSign can be anywhere.\n      atSign = rest.lastIndexOf('@');\n    } else {\n      // atSign must be in auth portion.\n      // http://a@b/c@d => host:b auth:a path:/c@d\n      atSign = rest.lastIndexOf('@', hostEnd);\n    } // Now we have a portion which is definitely the auth.\n    // Pull that off.\n\n\n    if (atSign !== -1) {\n      auth = rest.slice(0, atSign);\n      rest = rest.slice(atSign + 1);\n      this.auth = decodeURIComponent(auth);\n    } // the host is the remaining to the left of the first non-host char\n\n\n    hostEnd = -1;\n\n    for (var i = 0; i < nonHostChars.length; i++) {\n      var hec = rest.indexOf(nonHostChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec;\n    } // if we still have not hit it, then the entire thing is a host.\n\n\n    if (hostEnd === -1) hostEnd = rest.length;\n    this.host = rest.slice(0, hostEnd);\n    rest = rest.slice(hostEnd); // pull out port.\n\n    this.parseHost(); // we've indicated that there is a hostname,\n    // so even if it's empty, it has to be present.\n\n    this.hostname = this.hostname || ''; // if hostname begins with [ and ends with ]\n    // assume that it's an IPv6 address.\n\n    var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']'; // validate a little.\n\n    if (!ipv6Hostname) {\n      var hostparts = this.hostname.split(/\\./);\n\n      for (var i = 0, l = hostparts.length; i < l; i++) {\n        var part = hostparts[i];\n        if (!part) continue;\n\n        if (!part.match(hostnamePartPattern)) {\n          var newpart = '';\n\n          for (var j = 0, k = part.length; j < k; j++) {\n            if (part.charCodeAt(j) > 127) {\n              // we replace non-ASCII char with a temporary placeholder\n              // we need this to make sure size of hostname is not\n              // broken by replacing non-ASCII by nothing\n              newpart += 'x';\n            } else {\n              newpart += part[j];\n            }\n          } // we test again with ASCII char only\n\n\n          if (!newpart.match(hostnamePartPattern)) {\n            var validParts = hostparts.slice(0, i);\n            var notHost = hostparts.slice(i + 1);\n            var bit = part.match(hostnamePartStart);\n\n            if (bit) {\n              validParts.push(bit[1]);\n              notHost.unshift(bit[2]);\n            }\n\n            if (notHost.length) {\n              rest = '/' + notHost.join('.') + rest;\n            }\n\n            this.hostname = validParts.join('.');\n            break;\n          }\n        }\n      }\n    }\n\n    if (this.hostname.length > hostnameMaxLen) {\n      this.hostname = '';\n    } else {\n      // hostnames are always lower case.\n      this.hostname = this.hostname.toLowerCase();\n    }\n\n    if (!ipv6Hostname) {\n      // IDNA Support: Returns a punycoded representation of \"domain\".\n      // It only converts parts of the domain name that\n      // have non-ASCII characters, i.e. it doesn't matter if\n      // you call it with a domain that already is ASCII-only.\n      this.hostname = punycode.toASCII(this.hostname);\n    }\n\n    var p = this.port ? ':' + this.port : '';\n    var h = this.hostname || '';\n    this.host = h + p;\n    this.href += this.host; // strip [ and ] from the hostname\n    // the host field still retains them, though\n\n    if (ipv6Hostname) {\n      this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n\n      if (rest[0] !== '/') {\n        rest = '/' + rest;\n      }\n    }\n  } // now rest is set to the post-host stuff.\n  // chop off any delim chars.\n\n\n  if (!unsafeProtocol[lowerProto]) {\n    // First, make 100% sure that any \"autoEscape\" chars get\n    // escaped, even if encodeURIComponent doesn't think they\n    // need to be.\n    for (var i = 0, l = autoEscape.length; i < l; i++) {\n      var ae = autoEscape[i];\n      if (rest.indexOf(ae) === -1) continue;\n      var esc = encodeURIComponent(ae);\n\n      if (esc === ae) {\n        esc = escape(ae);\n      }\n\n      rest = rest.split(ae).join(esc);\n    }\n  } // chop off from the tail first.\n\n\n  var hash = rest.indexOf('#');\n\n  if (hash !== -1) {\n    // got a fragment string.\n    this.hash = rest.substr(hash);\n    rest = rest.slice(0, hash);\n  }\n\n  var qm = rest.indexOf('?');\n\n  if (qm !== -1) {\n    this.search = rest.substr(qm);\n    this.query = rest.substr(qm + 1);\n\n    if (parseQueryString) {\n      this.query = querystring.parse(this.query);\n    }\n\n    rest = rest.slice(0, qm);\n  } else if (parseQueryString) {\n    // no query string, but parseQueryString still requested\n    this.search = '';\n    this.query = {};\n  }\n\n  if (rest) this.pathname = rest;\n\n  if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) {\n    this.pathname = '/';\n  } //to support http.request\n\n\n  if (this.pathname || this.search) {\n    var p = this.pathname || '';\n    var s = this.search || '';\n    this.path = p + s;\n  } // finally, reconstruct the href based on what has been validated.\n\n\n  this.href = this.format();\n  return this;\n}; // format a parsed object into a url string\n\n\nfunction urlFormat(obj) {\n  // ensure it's an object, and not a string url.\n  // If it's an obj, this is a no-op.\n  // this way, you can call url_format() on strings\n  // to clean up potentially wonky urls.\n  if (util.isString(obj)) obj = urlParse(obj);\n  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);\n  return obj.format();\n}\n\nUrl.prototype.format = function () {\n  var auth = this.auth || '';\n\n  if (auth) {\n    auth = encodeURIComponent(auth);\n    auth = auth.replace(/%3A/i, ':');\n    auth += '@';\n  }\n\n  var protocol = this.protocol || '',\n      pathname = this.pathname || '',\n      hash = this.hash || '',\n      host = false,\n      query = '';\n\n  if (this.host) {\n    host = auth + this.host;\n  } else if (this.hostname) {\n    host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']');\n\n    if (this.port) {\n      host += ':' + this.port;\n    }\n  }\n\n  if (this.query && util.isObject(this.query) && Object.keys(this.query).length) {\n    query = querystring.stringify(this.query);\n  }\n\n  var search = this.search || query && '?' + query || '';\n  if (protocol && protocol.substr(-1) !== ':') protocol += ':'; // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.\n  // unless they had them to begin with.\n\n  if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) {\n    host = '//' + (host || '');\n    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;\n  } else if (!host) {\n    host = '';\n  }\n\n  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;\n  if (search && search.charAt(0) !== '?') search = '?' + search;\n  pathname = pathname.replace(/[?#]/g, function (match) {\n    return encodeURIComponent(match);\n  });\n  search = search.replace('#', '%23');\n  return protocol + host + pathname + search + hash;\n};\n\nfunction urlResolve(source, relative) {\n  return urlParse(source, false, true).resolve(relative);\n}\n\nUrl.prototype.resolve = function (relative) {\n  return this.resolveObject(urlParse(relative, false, true)).format();\n};\n\nfunction urlResolveObject(source, relative) {\n  if (!source) return relative;\n  return urlParse(source, false, true).resolveObject(relative);\n}\n\nUrl.prototype.resolveObject = function (relative) {\n  if (util.isString(relative)) {\n    var rel = new Url();\n    rel.parse(relative, false, true);\n    relative = rel;\n  }\n\n  var result = new Url();\n  var tkeys = Object.keys(this);\n\n  for (var tk = 0; tk < tkeys.length; tk++) {\n    var tkey = tkeys[tk];\n    result[tkey] = this[tkey];\n  } // hash is always overridden, no matter what.\n  // even href=\"\" will remove it.\n\n\n  result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here.\n\n  if (relative.href === '') {\n    result.href = result.format();\n    return result;\n  } // hrefs like //foo/bar always cut to the protocol.\n\n\n  if (relative.slashes && !relative.protocol) {\n    // take everything except the protocol from relative\n    var rkeys = Object.keys(relative);\n\n    for (var rk = 0; rk < rkeys.length; rk++) {\n      var rkey = rkeys[rk];\n      if (rkey !== 'protocol') result[rkey] = relative[rkey];\n    } //urlParse appends trailing / to urls like http://www.example.com\n\n\n    if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) {\n      result.path = result.pathname = '/';\n    }\n\n    result.href = result.format();\n    return result;\n  }\n\n  if (relative.protocol && relative.protocol !== result.protocol) {\n    // if it's a known url protocol, then changing\n    // the protocol does weird things\n    // first, if it's not file:, then we MUST have a host,\n    // and if there was a path\n    // to begin with, then we MUST have a path.\n    // if it is file:, then the host is dropped,\n    // because that's known to be hostless.\n    // anything else is assumed to be absolute.\n    if (!slashedProtocol[relative.protocol]) {\n      var keys = Object.keys(relative);\n\n      for (var v = 0; v < keys.length; v++) {\n        var k = keys[v];\n        result[k] = relative[k];\n      }\n\n      result.href = result.format();\n      return result;\n    }\n\n    result.protocol = relative.protocol;\n\n    if (!relative.host && !hostlessProtocol[relative.protocol]) {\n      var relPath = (relative.pathname || '').split('/');\n\n      while (relPath.length && !(relative.host = relPath.shift()));\n\n      if (!relative.host) relative.host = '';\n      if (!relative.hostname) relative.hostname = '';\n      if (relPath[0] !== '') relPath.unshift('');\n      if (relPath.length < 2) relPath.unshift('');\n      result.pathname = relPath.join('/');\n    } else {\n      result.pathname = relative.pathname;\n    }\n\n    result.search = relative.search;\n    result.query = relative.query;\n    result.host = relative.host || '';\n    result.auth = relative.auth;\n    result.hostname = relative.hostname || relative.host;\n    result.port = relative.port; // to support http.request\n\n    if (result.pathname || result.search) {\n      var p = result.pathname || '';\n      var s = result.search || '';\n      result.path = p + s;\n    }\n\n    result.slashes = result.slashes || relative.slashes;\n    result.href = result.format();\n    return result;\n  }\n\n  var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/',\n      isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/',\n      mustEndAbs = isRelAbs || isSourceAbs || result.host && relative.pathname,\n      removeAllDots = mustEndAbs,\n      srcPath = result.pathname && result.pathname.split('/') || [],\n      relPath = relative.pathname && relative.pathname.split('/') || [],\n      psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative\n  // links like ../.. should be able\n  // to crawl up to the hostname, as well.  This is strange.\n  // result.protocol has already been set by now.\n  // Later on, put the first path part into the host field.\n\n  if (psychotic) {\n    result.hostname = '';\n    result.port = null;\n\n    if (result.host) {\n      if (srcPath[0] === '') srcPath[0] = result.host;else srcPath.unshift(result.host);\n    }\n\n    result.host = '';\n\n    if (relative.protocol) {\n      relative.hostname = null;\n      relative.port = null;\n\n      if (relative.host) {\n        if (relPath[0] === '') relPath[0] = relative.host;else relPath.unshift(relative.host);\n      }\n\n      relative.host = null;\n    }\n\n    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');\n  }\n\n  if (isRelAbs) {\n    // it's absolute.\n    result.host = relative.host || relative.host === '' ? relative.host : result.host;\n    result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname;\n    result.search = relative.search;\n    result.query = relative.query;\n    srcPath = relPath; // fall through to the dot-handling below.\n  } else if (relPath.length) {\n    // it's relative\n    // throw away the existing file, and take the new path instead.\n    if (!srcPath) srcPath = [];\n    srcPath.pop();\n    srcPath = srcPath.concat(relPath);\n    result.search = relative.search;\n    result.query = relative.query;\n  } else if (!util.isNullOrUndefined(relative.search)) {\n    // just pull out the search.\n    // like href='?foo'.\n    // Put this after the other two cases because it simplifies the booleans\n    if (psychotic) {\n      result.hostname = result.host = srcPath.shift(); //occationaly the auth can get stuck only in host\n      //this especially happens in cases like\n      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n\n      var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;\n\n      if (authInHost) {\n        result.auth = authInHost.shift();\n        result.host = result.hostname = authInHost.shift();\n      }\n    }\n\n    result.search = relative.search;\n    result.query = relative.query; //to support http.request\n\n    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n      result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');\n    }\n\n    result.href = result.format();\n    return result;\n  }\n\n  if (!srcPath.length) {\n    // no path at all.  easy.\n    // we've already handled the other stuff above.\n    result.pathname = null; //to support http.request\n\n    if (result.search) {\n      result.path = '/' + result.search;\n    } else {\n      result.path = null;\n    }\n\n    result.href = result.format();\n    return result;\n  } // if a url ENDs in . or .., then it must get a trailing slash.\n  // however, if it ends in anything else non-slashy,\n  // then it must NOT get a trailing slash.\n\n\n  var last = srcPath.slice(-1)[0];\n  var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''; // strip single dots, resolve double dots to parent dir\n  // if the path tries to go above the root, `up` ends up > 0\n\n  var up = 0;\n\n  for (var i = srcPath.length; i >= 0; i--) {\n    last = srcPath[i];\n\n    if (last === '.') {\n      srcPath.splice(i, 1);\n    } else if (last === '..') {\n      srcPath.splice(i, 1);\n      up++;\n    } else if (up) {\n      srcPath.splice(i, 1);\n      up--;\n    }\n  } // if the path is allowed to go above the root, restore leading ..s\n\n\n  if (!mustEndAbs && !removeAllDots) {\n    for (; up--; up) {\n      srcPath.unshift('..');\n    }\n  }\n\n  if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {\n    srcPath.unshift('');\n  }\n\n  if (hasTrailingSlash && srcPath.join('/').substr(-1) !== '/') {\n    srcPath.push('');\n  }\n\n  var isAbsolute = srcPath[0] === '' || srcPath[0] && srcPath[0].charAt(0) === '/'; // put the host back\n\n  if (psychotic) {\n    result.hostname = result.host = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; //occationaly the auth can get stuck only in host\n    //this especially happens in cases like\n    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n\n    var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;\n\n    if (authInHost) {\n      result.auth = authInHost.shift();\n      result.host = result.hostname = authInHost.shift();\n    }\n  }\n\n  mustEndAbs = mustEndAbs || result.host && srcPath.length;\n\n  if (mustEndAbs && !isAbsolute) {\n    srcPath.unshift('');\n  }\n\n  if (!srcPath.length) {\n    result.pathname = null;\n    result.path = null;\n  } else {\n    result.pathname = srcPath.join('/');\n  } //to support request.http\n\n\n  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n    result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');\n  }\n\n  result.auth = relative.auth || result.auth;\n  result.slashes = result.slashes || relative.slashes;\n  result.href = result.format();\n  return result;\n};\n\nUrl.prototype.parseHost = function () {\n  var host = this.host;\n  var port = portPattern.exec(host);\n\n  if (port) {\n    port = port[0];\n\n    if (port !== ':') {\n      this.port = port.substr(1);\n    }\n\n    host = host.substr(0, host.length - port.length);\n  }\n\n  if (host) this.hostname = host;\n};","map":{"version":3,"sources":["C:/Users/kkwan_000/Desktop/git/2017110269/minsung/node_modules/url/url.js"],"names":["punycode","require","util","exports","parse","urlParse","resolve","urlResolve","resolveObject","urlResolveObject","format","urlFormat","Url","protocol","slashes","auth","host","port","hostname","hash","search","query","pathname","path","href","protocolPattern","portPattern","simplePathPattern","delims","unwise","concat","autoEscape","nonHostChars","hostEndingChars","hostnameMaxLen","hostnamePartPattern","hostnamePartStart","unsafeProtocol","hostlessProtocol","slashedProtocol","querystring","url","parseQueryString","slashesDenoteHost","isObject","u","prototype","isString","TypeError","queryIndex","indexOf","splitter","uSplit","split","slashRegex","replace","join","rest","trim","length","simplePath","exec","substr","proto","lowerProto","toLowerCase","match","hostEnd","i","hec","atSign","lastIndexOf","slice","decodeURIComponent","parseHost","ipv6Hostname","hostparts","l","part","newpart","j","k","charCodeAt","validParts","notHost","bit","push","unshift","toASCII","p","h","ae","esc","encodeURIComponent","escape","qm","s","obj","call","Object","keys","stringify","charAt","source","relative","rel","result","tkeys","tk","tkey","rkeys","rk","rkey","v","relPath","shift","isSourceAbs","isRelAbs","mustEndAbs","removeAllDots","srcPath","psychotic","pop","isNullOrUndefined","authInHost","isNull","last","hasTrailingSlash","up","splice","isAbsolute"],"mappings":"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","sourcesContent":["// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar punycode = require('punycode');\nvar util = require('./util');\n\nexports.parse = urlParse;\nexports.resolve = urlResolve;\nexports.resolveObject = urlResolveObject;\nexports.format = urlFormat;\n\nexports.Url = Url;\n\nfunction Url() {\n  this.protocol = null;\n  this.slashes = null;\n  this.auth = null;\n  this.host = null;\n  this.port = null;\n  this.hostname = null;\n  this.hash = null;\n  this.search = null;\n  this.query = null;\n  this.pathname = null;\n  this.path = null;\n  this.href = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n\n// define these here so at least they only have to be\n// compiled once on the first module load.\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n    portPattern = /:[0-9]*$/,\n\n    // Special case for a simple path URL\n    simplePathPattern = /^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,\n\n    // RFC 2396: characters reserved for delimiting URLs.\n    // We actually just auto-escape these.\n    delims = ['<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t'],\n\n    // RFC 2396: characters not allowed for various reasons.\n    unwise = ['{', '}', '|', '\\\\', '^', '`'].concat(delims),\n\n    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.\n    autoEscape = ['\\''].concat(unwise),\n    // Characters that are never ever allowed in a hostname.\n    // Note that any invalid chars are also handled, but these\n    // are the ones that are *expected* to be seen, so we fast-path\n    // them.\n    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),\n    hostEndingChars = ['/', '?', '#'],\n    hostnameMaxLen = 255,\n    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,\n    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,\n    // protocols that can allow \"unsafe\" and \"unwise\" chars.\n    unsafeProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that never have a hostname.\n    hostlessProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that always contain a // bit.\n    slashedProtocol = {\n      'http': true,\n      'https': true,\n      'ftp': true,\n      'gopher': true,\n      'file': true,\n      'http:': true,\n      'https:': true,\n      'ftp:': true,\n      'gopher:': true,\n      'file:': true\n    },\n    querystring = require('querystring');\n\nfunction urlParse(url, parseQueryString, slashesDenoteHost) {\n  if (url && util.isObject(url) && url instanceof Url) return url;\n\n  var u = new Url;\n  u.parse(url, parseQueryString, slashesDenoteHost);\n  return u;\n}\n\nUrl.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {\n  if (!util.isString(url)) {\n    throw new TypeError(\"Parameter 'url' must be a string, not \" + typeof url);\n  }\n\n  // Copy chrome, IE, opera backslash-handling behavior.\n  // Back slashes before the query string get converted to forward slashes\n  // See: https://code.google.com/p/chromium/issues/detail?id=25916\n  var queryIndex = url.indexOf('?'),\n      splitter =\n          (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',\n      uSplit = url.split(splitter),\n      slashRegex = /\\\\/g;\n  uSplit[0] = uSplit[0].replace(slashRegex, '/');\n  url = uSplit.join(splitter);\n\n  var rest = url;\n\n  // trim before proceeding.\n  // This is to support parse stuff like \"  http://foo.com  \\n\"\n  rest = rest.trim();\n\n  if (!slashesDenoteHost && url.split('#').length === 1) {\n    // Try fast path regexp\n    var simplePath = simplePathPattern.exec(rest);\n    if (simplePath) {\n      this.path = rest;\n      this.href = rest;\n      this.pathname = simplePath[1];\n      if (simplePath[2]) {\n        this.search = simplePath[2];\n        if (parseQueryString) {\n          this.query = querystring.parse(this.search.substr(1));\n        } else {\n          this.query = this.search.substr(1);\n        }\n      } else if (parseQueryString) {\n        this.search = '';\n        this.query = {};\n      }\n      return this;\n    }\n  }\n\n  var proto = protocolPattern.exec(rest);\n  if (proto) {\n    proto = proto[0];\n    var lowerProto = proto.toLowerCase();\n    this.protocol = lowerProto;\n    rest = rest.substr(proto.length);\n  }\n\n  // figure out if it's got a host\n  // user@server is *always* interpreted as a hostname, and url\n  // resolution will treat //foo/bar as host=foo,path=bar because that's\n  // how the browser resolves relative URLs.\n  if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n    var slashes = rest.substr(0, 2) === '//';\n    if (slashes && !(proto && hostlessProtocol[proto])) {\n      rest = rest.substr(2);\n      this.slashes = true;\n    }\n  }\n\n  if (!hostlessProtocol[proto] &&\n      (slashes || (proto && !slashedProtocol[proto]))) {\n\n    // there's a hostname.\n    // the first instance of /, ?, ;, or # ends the host.\n    //\n    // If there is an @ in the hostname, then non-host chars *are* allowed\n    // to the left of the last @ sign, unless some host-ending character\n    // comes *before* the @-sign.\n    // URLs are obnoxious.\n    //\n    // ex:\n    // http://a@b@c/ => user:a@b host:c\n    // http://a@b?@c => user:a host:c path:/?@c\n\n    // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n    // Review our test case against browsers more comprehensively.\n\n    // find the first instance of any hostEndingChars\n    var hostEnd = -1;\n    for (var i = 0; i < hostEndingChars.length; i++) {\n      var hec = rest.indexOf(hostEndingChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n\n    // at this point, either we have an explicit point where the\n    // auth portion cannot go past, or the last @ char is the decider.\n    var auth, atSign;\n    if (hostEnd === -1) {\n      // atSign can be anywhere.\n      atSign = rest.lastIndexOf('@');\n    } else {\n      // atSign must be in auth portion.\n      // http://a@b/c@d => host:b auth:a path:/c@d\n      atSign = rest.lastIndexOf('@', hostEnd);\n    }\n\n    // Now we have a portion which is definitely the auth.\n    // Pull that off.\n    if (atSign !== -1) {\n      auth = rest.slice(0, atSign);\n      rest = rest.slice(atSign + 1);\n      this.auth = decodeURIComponent(auth);\n    }\n\n    // the host is the remaining to the left of the first non-host char\n    hostEnd = -1;\n    for (var i = 0; i < nonHostChars.length; i++) {\n      var hec = rest.indexOf(nonHostChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n    // if we still have not hit it, then the entire thing is a host.\n    if (hostEnd === -1)\n      hostEnd = rest.length;\n\n    this.host = rest.slice(0, hostEnd);\n    rest = rest.slice(hostEnd);\n\n    // pull out port.\n    this.parseHost();\n\n    // we've indicated that there is a hostname,\n    // so even if it's empty, it has to be present.\n    this.hostname = this.hostname || '';\n\n    // if hostname begins with [ and ends with ]\n    // assume that it's an IPv6 address.\n    var ipv6Hostname = this.hostname[0] === '[' &&\n        this.hostname[this.hostname.length - 1] === ']';\n\n    // validate a little.\n    if (!ipv6Hostname) {\n      var hostparts = this.hostname.split(/\\./);\n      for (var i = 0, l = hostparts.length; i < l; i++) {\n        var part = hostparts[i];\n        if (!part) continue;\n        if (!part.match(hostnamePartPattern)) {\n          var newpart = '';\n          for (var j = 0, k = part.length; j < k; j++) {\n            if (part.charCodeAt(j) > 127) {\n              // we replace non-ASCII char with a temporary placeholder\n              // we need this to make sure size of hostname is not\n              // broken by replacing non-ASCII by nothing\n              newpart += 'x';\n            } else {\n              newpart += part[j];\n            }\n          }\n          // we test again with ASCII char only\n          if (!newpart.match(hostnamePartPattern)) {\n            var validParts = hostparts.slice(0, i);\n            var notHost = hostparts.slice(i + 1);\n            var bit = part.match(hostnamePartStart);\n            if (bit) {\n              validParts.push(bit[1]);\n              notHost.unshift(bit[2]);\n            }\n            if (notHost.length) {\n              rest = '/' + notHost.join('.') + rest;\n            }\n            this.hostname = validParts.join('.');\n            break;\n          }\n        }\n      }\n    }\n\n    if (this.hostname.length > hostnameMaxLen) {\n      this.hostname = '';\n    } else {\n      // hostnames are always lower case.\n      this.hostname = this.hostname.toLowerCase();\n    }\n\n    if (!ipv6Hostname) {\n      // IDNA Support: Returns a punycoded representation of \"domain\".\n      // It only converts parts of the domain name that\n      // have non-ASCII characters, i.e. it doesn't matter if\n      // you call it with a domain that already is ASCII-only.\n      this.hostname = punycode.toASCII(this.hostname);\n    }\n\n    var p = this.port ? ':' + this.port : '';\n    var h = this.hostname || '';\n    this.host = h + p;\n    this.href += this.host;\n\n    // strip [ and ] from the hostname\n    // the host field still retains them, though\n    if (ipv6Hostname) {\n      this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n      if (rest[0] !== '/') {\n        rest = '/' + rest;\n      }\n    }\n  }\n\n  // now rest is set to the post-host stuff.\n  // chop off any delim chars.\n  if (!unsafeProtocol[lowerProto]) {\n\n    // First, make 100% sure that any \"autoEscape\" chars get\n    // escaped, even if encodeURIComponent doesn't think they\n    // need to be.\n    for (var i = 0, l = autoEscape.length; i < l; i++) {\n      var ae = autoEscape[i];\n      if (rest.indexOf(ae) === -1)\n        continue;\n      var esc = encodeURIComponent(ae);\n      if (esc === ae) {\n        esc = escape(ae);\n      }\n      rest = rest.split(ae).join(esc);\n    }\n  }\n\n\n  // chop off from the tail first.\n  var hash = rest.indexOf('#');\n  if (hash !== -1) {\n    // got a fragment string.\n    this.hash = rest.substr(hash);\n    rest = rest.slice(0, hash);\n  }\n  var qm = rest.indexOf('?');\n  if (qm !== -1) {\n    this.search = rest.substr(qm);\n    this.query = rest.substr(qm + 1);\n    if (parseQueryString) {\n      this.query = querystring.parse(this.query);\n    }\n    rest = rest.slice(0, qm);\n  } else if (parseQueryString) {\n    // no query string, but parseQueryString still requested\n    this.search = '';\n    this.query = {};\n  }\n  if (rest) this.pathname = rest;\n  if (slashedProtocol[lowerProto] &&\n      this.hostname && !this.pathname) {\n    this.pathname = '/';\n  }\n\n  //to support http.request\n  if (this.pathname || this.search) {\n    var p = this.pathname || '';\n    var s = this.search || '';\n    this.path = p + s;\n  }\n\n  // finally, reconstruct the href based on what has been validated.\n  this.href = this.format();\n  return this;\n};\n\n// format a parsed object into a url string\nfunction urlFormat(obj) {\n  // ensure it's an object, and not a string url.\n  // If it's an obj, this is a no-op.\n  // this way, you can call url_format() on strings\n  // to clean up potentially wonky urls.\n  if (util.isString(obj)) obj = urlParse(obj);\n  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);\n  return obj.format();\n}\n\nUrl.prototype.format = function() {\n  var auth = this.auth || '';\n  if (auth) {\n    auth = encodeURIComponent(auth);\n    auth = auth.replace(/%3A/i, ':');\n    auth += '@';\n  }\n\n  var protocol = this.protocol || '',\n      pathname = this.pathname || '',\n      hash = this.hash || '',\n      host = false,\n      query = '';\n\n  if (this.host) {\n    host = auth + this.host;\n  } else if (this.hostname) {\n    host = auth + (this.hostname.indexOf(':') === -1 ?\n        this.hostname :\n        '[' + this.hostname + ']');\n    if (this.port) {\n      host += ':' + this.port;\n    }\n  }\n\n  if (this.query &&\n      util.isObject(this.query) &&\n      Object.keys(this.query).length) {\n    query = querystring.stringify(this.query);\n  }\n\n  var search = this.search || (query && ('?' + query)) || '';\n\n  if (protocol && protocol.substr(-1) !== ':') protocol += ':';\n\n  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.\n  // unless they had them to begin with.\n  if (this.slashes ||\n      (!protocol || slashedProtocol[protocol]) && host !== false) {\n    host = '//' + (host || '');\n    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;\n  } else if (!host) {\n    host = '';\n  }\n\n  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;\n  if (search && search.charAt(0) !== '?') search = '?' + search;\n\n  pathname = pathname.replace(/[?#]/g, function(match) {\n    return encodeURIComponent(match);\n  });\n  search = search.replace('#', '%23');\n\n  return protocol + host + pathname + search + hash;\n};\n\nfunction urlResolve(source, relative) {\n  return urlParse(source, false, true).resolve(relative);\n}\n\nUrl.prototype.resolve = function(relative) {\n  return this.resolveObject(urlParse(relative, false, true)).format();\n};\n\nfunction urlResolveObject(source, relative) {\n  if (!source) return relative;\n  return urlParse(source, false, true).resolveObject(relative);\n}\n\nUrl.prototype.resolveObject = function(relative) {\n  if (util.isString(relative)) {\n    var rel = new Url();\n    rel.parse(relative, false, true);\n    relative = rel;\n  }\n\n  var result = new Url();\n  var tkeys = Object.keys(this);\n  for (var tk = 0; tk < tkeys.length; tk++) {\n    var tkey = tkeys[tk];\n    result[tkey] = this[tkey];\n  }\n\n  // hash is always overridden, no matter what.\n  // even href=\"\" will remove it.\n  result.hash = relative.hash;\n\n  // if the relative url is empty, then there's nothing left to do here.\n  if (relative.href === '') {\n    result.href = result.format();\n    return result;\n  }\n\n  // hrefs like //foo/bar always cut to the protocol.\n  if (relative.slashes && !relative.protocol) {\n    // take everything except the protocol from relative\n    var rkeys = Object.keys(relative);\n    for (var rk = 0; rk < rkeys.length; rk++) {\n      var rkey = rkeys[rk];\n      if (rkey !== 'protocol')\n        result[rkey] = relative[rkey];\n    }\n\n    //urlParse appends trailing / to urls like http://www.example.com\n    if (slashedProtocol[result.protocol] &&\n        result.hostname && !result.pathname) {\n      result.path = result.pathname = '/';\n    }\n\n    result.href = result.format();\n    return result;\n  }\n\n  if (relative.protocol && relative.protocol !== result.protocol) {\n    // if it's a known url protocol, then changing\n    // the protocol does weird things\n    // first, if it's not file:, then we MUST have a host,\n    // and if there was a path\n    // to begin with, then we MUST have a path.\n    // if it is file:, then the host is dropped,\n    // because that's known to be hostless.\n    // anything else is assumed to be absolute.\n    if (!slashedProtocol[relative.protocol]) {\n      var keys = Object.keys(relative);\n      for (var v = 0; v < keys.length; v++) {\n        var k = keys[v];\n        result[k] = relative[k];\n      }\n      result.href = result.format();\n      return result;\n    }\n\n    result.protocol = relative.protocol;\n    if (!relative.host && !hostlessProtocol[relative.protocol]) {\n      var relPath = (relative.pathname || '').split('/');\n      while (relPath.length && !(relative.host = relPath.shift()));\n      if (!relative.host) relative.host = '';\n      if (!relative.hostname) relative.hostname = '';\n      if (relPath[0] !== '') relPath.unshift('');\n      if (relPath.length < 2) relPath.unshift('');\n      result.pathname = relPath.join('/');\n    } else {\n      result.pathname = relative.pathname;\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    result.host = relative.host || '';\n    result.auth = relative.auth;\n    result.hostname = relative.hostname || relative.host;\n    result.port = relative.port;\n    // to support http.request\n    if (result.pathname || result.search) {\n      var p = result.pathname || '';\n      var s = result.search || '';\n      result.path = p + s;\n    }\n    result.slashes = result.slashes || relative.slashes;\n    result.href = result.format();\n    return result;\n  }\n\n  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),\n      isRelAbs = (\n          relative.host ||\n          relative.pathname && relative.pathname.charAt(0) === '/'\n      ),\n      mustEndAbs = (isRelAbs || isSourceAbs ||\n                    (result.host && relative.pathname)),\n      removeAllDots = mustEndAbs,\n      srcPath = result.pathname && result.pathname.split('/') || [],\n      relPath = relative.pathname && relative.pathname.split('/') || [],\n      psychotic = result.protocol && !slashedProtocol[result.protocol];\n\n  // if the url is a non-slashed url, then relative\n  // links like ../.. should be able\n  // to crawl up to the hostname, as well.  This is strange.\n  // result.protocol has already been set by now.\n  // Later on, put the first path part into the host field.\n  if (psychotic) {\n    result.hostname = '';\n    result.port = null;\n    if (result.host) {\n      if (srcPath[0] === '') srcPath[0] = result.host;\n      else srcPath.unshift(result.host);\n    }\n    result.host = '';\n    if (relative.protocol) {\n      relative.hostname = null;\n      relative.port = null;\n      if (relative.host) {\n        if (relPath[0] === '') relPath[0] = relative.host;\n        else relPath.unshift(relative.host);\n      }\n      relative.host = null;\n    }\n    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');\n  }\n\n  if (isRelAbs) {\n    // it's absolute.\n    result.host = (relative.host || relative.host === '') ?\n                  relative.host : result.host;\n    result.hostname = (relative.hostname || relative.hostname === '') ?\n                      relative.hostname : result.hostname;\n    result.search = relative.search;\n    result.query = relative.query;\n    srcPath = relPath;\n    // fall through to the dot-handling below.\n  } else if (relPath.length) {\n    // it's relative\n    // throw away the existing file, and take the new path instead.\n    if (!srcPath) srcPath = [];\n    srcPath.pop();\n    srcPath = srcPath.concat(relPath);\n    result.search = relative.search;\n    result.query = relative.query;\n  } else if (!util.isNullOrUndefined(relative.search)) {\n    // just pull out the search.\n    // like href='?foo'.\n    // Put this after the other two cases because it simplifies the booleans\n    if (psychotic) {\n      result.hostname = result.host = srcPath.shift();\n      //occationaly the auth can get stuck only in host\n      //this especially happens in cases like\n      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n      var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                       result.host.split('@') : false;\n      if (authInHost) {\n        result.auth = authInHost.shift();\n        result.host = result.hostname = authInHost.shift();\n      }\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    //to support http.request\n    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n      result.path = (result.pathname ? result.pathname : '') +\n                    (result.search ? result.search : '');\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  if (!srcPath.length) {\n    // no path at all.  easy.\n    // we've already handled the other stuff above.\n    result.pathname = null;\n    //to support http.request\n    if (result.search) {\n      result.path = '/' + result.search;\n    } else {\n      result.path = null;\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  // if a url ENDs in . or .., then it must get a trailing slash.\n  // however, if it ends in anything else non-slashy,\n  // then it must NOT get a trailing slash.\n  var last = srcPath.slice(-1)[0];\n  var hasTrailingSlash = (\n      (result.host || relative.host || srcPath.length > 1) &&\n      (last === '.' || last === '..') || last === '');\n\n  // strip single dots, resolve double dots to parent dir\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = srcPath.length; i >= 0; i--) {\n    last = srcPath[i];\n    if (last === '.') {\n      srcPath.splice(i, 1);\n    } else if (last === '..') {\n      srcPath.splice(i, 1);\n      up++;\n    } else if (up) {\n      srcPath.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (!mustEndAbs && !removeAllDots) {\n    for (; up--; up) {\n      srcPath.unshift('..');\n    }\n  }\n\n  if (mustEndAbs && srcPath[0] !== '' &&\n      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {\n    srcPath.unshift('');\n  }\n\n  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {\n    srcPath.push('');\n  }\n\n  var isAbsolute = srcPath[0] === '' ||\n      (srcPath[0] && srcPath[0].charAt(0) === '/');\n\n  // put the host back\n  if (psychotic) {\n    result.hostname = result.host = isAbsolute ? '' :\n                                    srcPath.length ? srcPath.shift() : '';\n    //occationaly the auth can get stuck only in host\n    //this especially happens in cases like\n    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n    var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                     result.host.split('@') : false;\n    if (authInHost) {\n      result.auth = authInHost.shift();\n      result.host = result.hostname = authInHost.shift();\n    }\n  }\n\n  mustEndAbs = mustEndAbs || (result.host && srcPath.length);\n\n  if (mustEndAbs && !isAbsolute) {\n    srcPath.unshift('');\n  }\n\n  if (!srcPath.length) {\n    result.pathname = null;\n    result.path = null;\n  } else {\n    result.pathname = srcPath.join('/');\n  }\n\n  //to support request.http\n  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n    result.path = (result.pathname ? result.pathname : '') +\n                  (result.search ? result.search : '');\n  }\n  result.auth = relative.auth || result.auth;\n  result.slashes = result.slashes || relative.slashes;\n  result.href = result.format();\n  return result;\n};\n\nUrl.prototype.parseHost = function() {\n  var host = this.host;\n  var port = portPattern.exec(host);\n  if (port) {\n    port = port[0];\n    if (port !== ':') {\n      this.port = port.substr(1);\n    }\n    host = host.substr(0, host.length - port.length);\n  }\n  if (host) this.hostname = host;\n};\n"]},"metadata":{},"sourceType":"script"}