The following algorithm is lifted from Node core: https://github.com/nodejs/node/blob/296bfd2/lib/_http_client.js#L90-L103
960733
function formatHostHeader (host, port, tls) {
  var defaultPort = tls ? 443 : 80
  var posColon = -1

  // For the Host header, ensure that IPv6 addresses are enclosed
  // in square brackets, as defined by URI formatting
  // https://tools.ietf.org/html/rfc3986#section-3.2.2
  if ((posColon = host.indexOf(':')) !== -1 &&
      (posColon = host.indexOf(':', posColon) !== -1) &&
      host[0] !== '[') {
    host = '[' + host + ']'
  }

  if (port && +port !== defaultPort) {
    host += ':' + port
  }

  return host
}
517095
def get_algorithm(algorithm):
    

    global _hashes
    if _hashes is None:
        _setup_hashes()

    if isinstance(algorithm, (str, unicode)):
        algorithm = dns.name.from_text(algorithm)

    if sys.hexversion < 0x02050200 and \
       (algorithm == HMAC_SHA384 or algorithm == HMAC_SHA512):
        raise NotImplementedError("TSIG algorithm " + str(algorithm) +
                                  " requires Python 2.5.2 or later")

    try:
        return (algorithm.to_digestable(), _hashes[algorithm])
    except KeyError:
        raise NotImplementedError("TSIG algorithm " + str(algorithm) +
                                  " is not supported")
473449
function hmacSha256(key, data) {
    if (subtle) {
        var algo = { name: 'HMAC', hash: { name: 'SHA-256' } };
        return subtle.importKey('raw', key, algo, false, ['sign'])
            .then(function(subtleKey) {
                return subtle.sign(algo, subtleKey, data);
            });
    } else if (nodeCrypto) {
        return new Promise(function(resolve) {
            var hmac = nodeCrypto.createHmac('sha256', Buffer.from(key));
            var hash = hmac.update(Buffer.from(data)).digest();
            resolve(hash.buffer);
        });
    } else {
        return Promise.reject(new KdbxError(Consts.ErrorCodes.NotImplemented, 'HMAC-SHA256 not implemented'));
    }
}
154895
function (string) {
         // TextEncoder + Uint8Array to binary string is faster than checking every bytes on long strings.
         // http://jsperf.com/utf8encode-vs-textencoder
         // On short strings (file names for example), the TextEncoder API is (currently) slower.
         if (JSZip.support.uint8array && typeof TextEncoder === "function") {
            var u8 = TextEncoder("utf-8").encode(string);
            return JSZip.utils.transformTo("string", u8);
         }
         if (JSZip.support.nodebuffer) {
            return JSZip.utils.transformTo("string", new Buffer(string, "utf-8"));
         }

         // array.join may be slower than string concatenation but generates less objects (less time spent garbage collecting).
         // See also http://jsperf.com/array-direct-assignment-vs-push/31
         var result = [], resIndex = 0;

         for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
               result[resIndex++] = String.fromCharCode(c);
            } else if ((c > 127) && (c < 2048)) {
               result[resIndex++] = String.fromCharCode((c >> 6) | 192);
               result[resIndex++] = String.fromCharCode((c & 63) | 128);
            } else {
               result[resIndex++] = String.fromCharCode((c >> 12) | 224);
               result[resIndex++] = String.fromCharCode(((c >> 6) & 63) | 128);
               result[resIndex++] = String.fromCharCode((c & 63) | 128);
            }

         }

         return result.join("");
      }
935652
function binarySearch(arr, callback, start, end, returnNearestIfNoHit) {
  var max = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1000;
  var midNum;
  var mid;

  if (start == null) {
    start = 0;
    end = arr.length - 1;
  }

  var i = 0;
  var r;

  while (start >= 0 && start <= end) {
    if (i >= max) {
      throw Error("binarySearch: loop times is over ".concat(max, ", you can increase the limit."));
    }

    midNum = Math.floor((end - start) / 2 + start);
    mid = arr[midNum];
    r = callback(mid, i);

    if (r > 0) {
      end = midNum - 1;
    } else if (r < 0) {
      start = midNum + 1;
    } else {
      return {
        index: midNum,
        value: mid,
        count: i + 1,
        hit: true
      };
    }

    i++;
  }

  return returnNearestIfNoHit ? {
    index: midNum,
    value: mid,
    count: i + 1,
    hit: false,
    bigger: r > 0
  } : null;
}
177445
function HttpTool(){
        this.settings = {};
        this.urlObject = {};
        this.dataToWrite = '';
        // ********** Helper Functions/Members **********
        
        var validMethods = ['GET', 'PUT', 'POST', 'DELETE', 'PATCH'];
        
        /**
        * Make sure that settings has at least property of url and method.
        * @return {boolean} whether settings is valid.
        */ 
        this.isSettingValid = function(settings){
            if (_.isEmpty(settings)) {
                return false;
            }
            if ( ! (settings.hasOwnProperty('url') && settings.hasOwnProperty('method'))) {
                return false;
            }
            if (_.isEmpty(settings.url) || _.isEmpty(settings.method)) {
                return false;
            }
            if (_.indexOf(validMethods, settings.method) === -1) {
                return false;    
            }

            return true;
        };

        /**
        * Parse and convert setting into a urlObject that suitable for 
        * http/https module in NodeJs.
        * @return {object} - the object that suitable for Node http/https module.
        */
        this.setupUrlOptions = function(settings) {
                
            var urlTool = require('url');
            var urlObject = {};

            // Parse the string into url options
            if (typeof (settings.url) === 'string') {
                urlObject = urlTool.parse(settings.url);
            }
            else {
                urlObject = settings.url;
            }
            // set the REST options
            urlObject.method = settings.method;
        
            // set up the REST headers
            if (! _.isEmpty(settings.headers)){
                urlObject.headers = settings.headers;
            }
            else {
                urlObject.headers = {};
            }
            
            urlObject.headers['Content-Length'] = 0;
            if (settings.hasOwnProperty('data')){
                switch (typeof settings.data) {
                    case 'object':
                        this.dataToWrite = JSON.stringify(settings.data);
                        urlObject.headers['Content-Type'] = 'application/json';
                        break;
                    case 'string':
                        this.dataToWrite = settings.data;
                        break;
                    default:
                        throw new TypeError("Data field can only be object or string," + 
                                            " but got " + (typeof settings.data));
                                        }
                urlObject.headers['Content-Length'] = Buffer.byteLength(this.dataToWrite);
            }
            
            if (! _.isEmpty(settings.credential)){
                if (!_.isEmpty(settings.credential.password) &&
                    _.isEmpty(settings.credential.username)) {
                    throw new Error('Please provide username and password '+
                                    'for basic authentication.');
                }
                else {
                    urlObject.auth = settings.credential.username +':'+
                    settings.credential.password;
                }
            }
            
            // set the protolcol paramter
            if (urlObject.protocol.substr(-1) !== ':') {
                urlObject.protocol = urlObject.protocol + ':';
            }

            urlObject.rejectUnauthorized = settings.verifySSL || false;
            urlObject.recvTimeoutMs = settings.recvTimeoutMs;

            return urlObject;
        };
    }
1320856
function decodeArrayBuffer(array) {

    /* Speedup on Node.JS using native BASE64 */
    if (process && Buffer && (array['!$base64$!'] != null)) {
      return new Uint8Array(new Buffer(array['!$base64$!'], 'base64')).buffer
    }

    /* Normal array processing */
    return new Uint8Array(array).buffer;
  }
907823
function kargerStein() {
    var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;

    edges.unmergeBy(function (edge) {
      return edge.isLoop();
    });
    var numNodes = nodes.length;
    var numEdges = edges.length;
    var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2));
    var stopSize = Math.floor(numNodes / sqrt2);

    if (numNodes < 2) {
      error('At least 2 nodes are required for Karger-Stein algorithm');
      return undefined;
    } // Now store edge destination as indexes
    // Format for each edge (edge index, source node index, target node index)


    var edgeIndexes = [];

    for (var i = 0; i < numEdges; i++) {
      var e = edges[i];
      edgeIndexes.push([i, nodes.indexOf(e.source()), nodes.indexOf(e.target())]);
    } // We will store the best cut found here


    var minCutSize = Infinity;
    var minCutEdgeIndexes = [];
    var minCutNodeMap = new Array(numNodes); // Initial meta node partition

    var metaNodeMap = new Array(numNodes);
    var metaNodeMap2 = new Array(numNodes);

    var copyNodesMap = function copyNodesMap(from, to) {
      for (var _i3 = 0; _i3 < numNodes; _i3++) {
        to[_i3] = from[_i3];
      }
    }; // Main loop


    for (var iter = 0; iter <= numIter; iter++) {
      // Reset meta node partition
      for (var _i4 = 0; _i4 < numNodes; _i4++) {
        metaNodeMap[_i4] = _i4;
      } // Contract until stop point (stopSize nodes)


      var edgesState = contractUntil(metaNodeMap, edgeIndexes.slice(), numNodes, stopSize);
      var edgesState2 = edgesState.slice(); // copy
      // Create a copy of the colapsed nodes state

      copyNodesMap(metaNodeMap, metaNodeMap2); // Run 2 iterations starting in the stop state

      var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2);
      var res2 = contractUntil(metaNodeMap2, edgesState2, stopSize, 2); // Is any of the 2 results the best cut so far?

      if (res1.length <= res2.length && res1.length < minCutSize) {
        minCutSize = res1.length;
        minCutEdgeIndexes = res1;
        copyNodesMap(metaNodeMap, minCutNodeMap);
      } else if (res2.length <= res1.length && res2.length < minCutSize) {
        minCutSize = res2.length;
        minCutEdgeIndexes = res2;
        copyNodesMap(metaNodeMap2, minCutNodeMap);
      }
    } // end of main loop
    // Construct result


    var cut = this.spawn(minCutEdgeIndexes.map(function (e) {
      return edges[e[0]];
    }));
    var partition1 = this.spawn();
    var partition2 = this.spawn(); // traverse metaNodeMap for best cut

    var witnessNodePartition = minCutNodeMap[0];

    for (var _i5 = 0; _i5 < minCutNodeMap.length; _i5++) {
      var partitionId = minCutNodeMap[_i5];
      var node = nodes[_i5];

      if (partitionId === witnessNodePartition) {
        partition1.merge(node);
      } else {
        partition2.merge(node);
      }
    }

    var ret = {
      cut: cut,
      partition1: partition1,
      partition2: partition2
    };
    return ret;
  }
575919
function sha256(data) {
    if (!data.byteLength) {
        return Promise.resolve(ByteUtils.arrayToBuffer(ByteUtils.hexToBytes(EmptySha256)));
    }
    if (subtle) {
        return subtle.digest({ name: 'SHA-256' }, data);
    } else if (nodeCrypto) {
        return new Promise(function(resolve) {
            var sha = nodeCrypto.createHash('sha256');
            var hash = sha.update(Buffer.from(data)).digest();
            resolve(hash.buffer);
        });
    } else {
        return Promise.reject(new KdbxError(Consts.ErrorCodes.NotImplemented, 'SHA256 not implemented'));
    }
}
1030200
function getRNG(){
	var randomBits, crypto;
	
	function construct(bits, arr, radix, size){
		var str = '',
			i = 0,
			len = arr.length-1;
		while( i<len || (str.length < bits) ){
			str += padLeft(parseInt(arr[i], radix).toString(2), size);
			i++;
		}
		str = str.substr(-bits);
		if( (str.match(/0/g)||[]).length === str.length){ // all zeros?
			return null;
		}else{
			return str;
		}
	}
	
	// node.js crypto.randomBytes()
	if(typeof require === 'function' && (crypto=require('crypto')) && (randomBits=crypto['randomBytes'])){
		return function(bits){
			var bytes = Math.ceil(bits/8),
				str = null;
		
			while( str === null ){
				str = construct(bits, randomBits(bytes).toString('hex'), 16, 4);
			}
			return str;
		}
	}
	
	// browsers with window.crypto.getRandomValues()
	if(global['crypto'] && typeof global['crypto']['getRandomValues'] === 'function' && typeof global['Uint32Array'] === 'function'){
		crypto = global['crypto'];
		return function(bits){
			var elems = Math.ceil(bits/32),
				str = null,
				arr = new global['Uint32Array'](elems);

			while( str === null ){
				crypto['getRandomValues'](arr);
				str = construct(bits, arr, 10, 32);
			}
			
			return str;	
		}
	}

	// A totally insecure RNG!!! (except in Safari)
	// Will produce a warning every time it is called.
	config.unsafePRNG = true;
	warn();
	
	var bitsPerNum = 32;
	var max = Math.pow(2,bitsPerNum)-1;
	return function(bits){
		var elems = Math.ceil(bits/bitsPerNum);
		var arr = [], str=null;
		while(str===null){
			for(var i=0; i<elems; i++){
				arr[i] = Math.floor(Math.random() * max + 1); 
			}
			str = construct(bits, arr, 10, bitsPerNum);
		}
		return str;
	};
}
595719
function getMixin1() {
  const type = NodeType.MixinType;
  const token = tokens[pos];
  const line = token.ln;
  const column = token.col;
  let content = [];

  content.push(checkClass(pos) ? getClass() : getShash());

  content = content.concat(getSC());

  if (checkArguments(pos)) content.push(getArguments());

  content = content.concat(getSC());

  if (checkBlock(pos)) content.push(getBlock());

  return newNode(type, content, line, column);
}
581742
function unzipNodeTarball(next) {
        var onError = function(err) {
          console.log(err.stack);
          _log('error', 'failed to extract the node source');
          process.exit(1);
        };

        if (isWin) {
          _log('extracting the node source [node-tar.gz]');

          // tar-stream method w/ gunzip-maybe
          var read = fs.createReadStream(nodeFilePath);
          var extract = tarstream.extract();
          var basedir = nodeFileDir;

          if (!fs.existsSync(nodeFileDir)) {
            fs.mkdirSync(nodeFileDir);
          }

          extract.on('entry', function(header, stream, callback) {
            // header is the tar header
            // stream is the content body (might be an empty stream)
            // call next when you are done with this entry

            var absolutepath = path.join(basedir, header.name);
            if (header.type === 'directory') {
              // handle directories.
              // console.log('dir:', header.name);
              fs.mkdirSync(absolutepath);
              return callback();
            } else if (header.type === 'file') {
              // handle files
              // console.log('file:', header.name);
            } else {
              console.log(header.type + ':', header.name);
              _log('warn', 'unhandled type in tar extraction, skipping');
              return callback();
            }

            var write = fs.createWriteStream(absolutepath);

            stream.pipe(write);

            write.on('close', function() {
              return callback();
            });

            stream.on('error', function(err) {
              return onError(err);
            });

            write.on('error', function(err) {
              return onError(err);
            });

            stream.resume(); // just auto drain the stream
          });

          extract.on('finish', function() {
            _log('extraction finished');
            return next();
          });

          read.pipe(gunzip()).pipe(extract);
        } else {
          _log('extracting the node source [native tar]');

          var cmd = ['tar', '-xf', nodeFilePath, '-C', nodeFileDir];
          _log(cmd.join(' '));

          var tar = spawn(cmd.shift(), cmd);
          tar.stdout.pipe(process.stdout);
          tar.stderr.pipe(process.stderr);

          tar.on('close', function() {
            return next();
          });
          tar.on('error', onError);
        }
      }
217434
function(encoded) {
      if (encoded instanceof Array) {
        encoded = encoded.map(function(chunk) {return chunk.replace(/^0x/g, '')}).join('');
      }

      // Each symbol is 4 bits
      var result = [];
      var nextIndex = 0;
      while (nextIndex < encoded.length) {
        var schemaLength = parseInt(encoded.slice(nextIndex, nextIndex + 1 * 2), 16);
        var idLength = parseInt(encoded.slice(nextIndex + (1 + schemaLength) * 2, nextIndex + (1 + schemaLength + 2) * 2), 16);

        var schema = encoded.slice(nextIndex + 1 * 2, nextIndex + (1 + schemaLength) * 2);
        // Convert to string
        schema = hexToString(schema);
        var idHex = encoded.slice(nextIndex + (1 + schemaLength + 2) * 2, nextIndex + (1 + schemaLength + 2 + idLength) * 2);
        var id = schema.match(allowedProtocolsRegExp) ? idHex : hexToString(idHex);
        result.push(schema + ':' + id);

        // Get full cells
        var cellsPerId = Math.ceil((1 + schemaLength + 2 + idLength) / 32);
        nextIndex += cellsPerId * 32 * 2;
      }

      return result;
    }
612059
function P_hash(secret, seed, outputLength, algorithm) {
    let result = Buffer.alloc(0); // empty buffer
    let hmac;

    // for the initial iteration, set the (initial) data to our seed
    let data = seed;
    while (result.length < outputLength) {
        // calculate the hmac for our current 'data' value (our seed on the initiatial iteration...or an iterative hmac of that seed in later iterations)
        hmac = exports.crypto.createHmac(algorithm, secret).update(data).digest();
        // save this hmac result as the 'data' input for the next iteration
        let dataForNextIteration = hmac;
        // concatenate the hmac and our seed
        data = Buffer.concat([hmac, seed]);
        // calculate an hmac for the hmac-plus-seed (which we will store in our output)
        hmac = exports.crypto.createHmac(algorithm, secret).update(data).digest();
        // add the hmac to our result
        result = Buffer.concat([result, hmac]);
        // restore the saved first-interation-stage hmac as the 'data' input for our next iteration
        data = dataForNextIteration;
    }

    // if our HMAC's output block size resulted in a length which is slightly too big, discard the extra bytes.
    if (result.length > outputLength) {
        let truncatedBuffer = Buffer.alloc(outputLength);
        result.copy(truncatedBuffer, 0, 0, outputLength);
        result = truncatedBuffer;
    }

    // return the hash result (with the number of octects/bytes specified as 'outputLength' by the caller)
    return result;
}
423661
function parseASCIIChunk(workChunk) {
  var data = (0, _utils.ensureString)(workChunk);
  // console.log('parseASCII')
  var result = void 0,
      text = void 0;
  var patternNormal = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
  var patternVertex = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
  var patternFace = /facet([\s\S]*?)endfacet/g;

  var posArray = [];
  var normArray = [];

  var faces = 0;
  var offset = 0;

  while ((result = patternFace.exec(data)) !== null) {
    var length = 0;

    text = result[0];
    offset = result.index + text.length;

    while ((result = patternNormal.exec(text)) !== null) {
      normArray.push(parseFloat(result[1]), parseFloat(result[3]), parseFloat(result[5]));
      normArray.push(parseFloat(result[1]), parseFloat(result[3]), parseFloat(result[5]));
      normArray.push(parseFloat(result[1]), parseFloat(result[3]), parseFloat(result[5]));
    }

    while ((result = patternVertex.exec(text)) !== null) {
      posArray.push(parseFloat(result[1]), parseFloat(result[3]), parseFloat(result[5]));
      length += 1;
    }
    faces += 1;
  }

  var positions = new Float32Array(faces * 3 * 3);
  var normals = new Float32Array(faces * 3 * 3);

  positions.set(posArray);
  normals.set(normArray);

  // compute offsets, remainderData etc for next chunk etc
  var remainderTextData = data.slice(offset);
  // console.log('remainderData', remainderTextData)
  var remainderData = new Buffer(remainderTextData);
  return { faceOffset: faces, remainderData: remainderData, positions: positions, normals: normals };
}
825503
function getHash(str, algorithm) {
  algorithm = algorithm || 'md5';
  var hash = crypto.createHash(algorithm);
  hash.end(str);
  return hash.read();
}
1289039
function getUri() {
  const startPos = pos;
  const type = NodeType.UriType;
  const token = tokens[startPos];
  const line = token.ln;
  const column = token.col;
  let content = [];
  let end;

  const uriType = tokens[startPos].uriType;

  // Skip `url` and `(`.
  pos += 2;

  if (uriType === 1) content = content.concat(getUri1());
  else if (uriType === 2) content = content.concat(getUri2());
  else end = getLastPosition(content, line, column, 4);

  if (!end) end = getLastPosition(content, line, column, 1);

  // Skip `)`.
  pos++;

  return newNode(type, content, line, column, end);
}