text: function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  
  var os = _interopDefault(require('os'));
  var fs = _interopDefault(require('fs'));
  var path = _interopDefault(require('path'));
  var Url = _interopDefault(require('url'));
  var events = _interopDefault(require('events'));
  var util = _interopDefault(require('util'));
  var Stream = _interopDefault(require('stream'));
  var http = _interopDefault(require('http'));
  var https = _interopDefault(require('https'));
  var tls = _interopDefault(require('tls'));
  var dns = _interopDefault(require('dns'));
  var buffer$1 = _interopDefault(require('buffer'));
  var zlib = _interopDefault(require('zlib'));
  var http2 = _interopDefault(require('http2'));
  var net = _interopDefault(require('net'));
  require('assert');
  
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
  
  function unwrapExports (x) {
  	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
  }
  
  function createCommonjsModule(fn, basedir, module) {
  	return module = {
  	  path: basedir,
  	  exports: {},
  	  require: function (path, base) {
        return commonjsRequire();
      }
  	}, fn(module, module.exports), module.exports;
  }
  
  function commonjsRequire () {
  	throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
  }
  
  var utils = createCommonjsModule(function (module, exports) {
  // We use any as a valid input type
  /* eslint-disable @typescript-eslint/no-explicit-any */
  Object.defineProperty(exports, "__esModule", { value: true });
  /**
   * Sanitizes an input into a string so it can be passed into issueCommand safely
   * @param input input to sanitize into a string
   */
  function toCommandValue(input) {
      if (input === null || input === undefined) {
          return '';
      }
      else if (typeof input === 'string' || input instanceof String) {
          return input;
      }
      return JSON.stringify(input);
  }
  exports.toCommandValue = toCommandValue;
  
  });
  
  var command = createCommonjsModule(function (module, exports) {
  var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
      result["default"] = mod;
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const os$1 = __importStar(os);
  
  /**
   * Commands
   *
   * Command Format:
   *   ::name key=value,key=value::message
   *
   * Examples:
   *   ::warning::This is the message
   *   ::set-env name=MY_VAR::some value
   */
  function issueCommand(command, properties, message) {
      const cmd = new Command(command, properties, message);
      process.stdout.write(cmd.toString() + os$1.EOL);
  }
  exports.issueCommand = issueCommand;
  function issue(name, message = '') {
      issueCommand(name, {}, message);
  }
  exports.issue = issue;
  const CMD_STRING = '::';
  class Command {
      constructor(command, properties, message) {
          if (!command) {
              command = 'missing.command';
          }
          this.command = command;
          this.properties = properties;
          this.message = message;
      }
      toString() {
          let cmdStr = CMD_STRING + this.command;
          if (this.properties && Object.keys(this.properties).length > 0) {
              cmdStr += ' ';
              let first = true;
              for (const key in this.properties) {
                  if (this.properties.hasOwnProperty(key)) {
                      const val = this.properties[key];
                      if (val) {
                          if (first) {
                              first = false;
                          }
                          else {
                              cmdStr += ',';
                          }
                          cmdStr += `${key}=${escapeProperty(val)}`;
                      }
                  }
              }
          }
          cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
          return cmdStr;
      }
  }
  function escapeData(s) {
      return utils.toCommandValue(s)
          .replace(/%/g, '%25')
          .replace(/\r/g, '%0D')
          .replace(/\n/g, '%0A');
  }
  function escapeProperty(s) {
      return utils.toCommandValue(s)
          .replace(/%/g, '%25')
          .replace(/\r/g, '%0D')
          .replace(/\n/g, '%0A')
          .replace(/:/g, '%3A')
          .replace(/,/g, '%2C');
  }
  
  });
  
  var fileCommand = createCommonjsModule(function (module, exports) {
  // For internal use, subject to change.
  var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
      result["default"] = mod;
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  // We use any as a valid input type
  /* eslint-disable @typescript-eslint/no-explicit-any */
  const fs$1 = __importStar(fs);
  const os$1 = __importStar(os);
  
  function issueCommand(command, message) {
      const filePath = process.env[`GITHUB_${command}`];
      if (!filePath) {
          throw new Error(`Unable to find environment variable for file command ${command}`);
      }
      if (!fs$1.existsSync(filePath)) {
          throw new Error(`Missing file at path: ${filePath}`);
      }
      fs$1.appendFileSync(filePath, `${utils.toCommandValue(message)}${os$1.EOL}`, {
          encoding: 'utf8'
      });
  }
  exports.issueCommand = issueCommand;
  
  });
  
  var core = createCommonjsModule(function (module, exports) {
  var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) {
      function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
      return new (P || (P = Promise))(function (resolve, reject) {
          function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
          function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
          function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
          step((generator = generator.apply(thisArg, _arguments || [])).next());
      });
  };
  var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
      result["default"] = mod;
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  
  
  
  const os$1 = __importStar(os);
  const path$1 = __importStar(path);
  /**
   * The code to exit an action
   */
  var ExitCode;
  (function (ExitCode) {
      /**
       * A code indicating that the action was successful
       */
      ExitCode[ExitCode["Success"] = 0] = "Success";
      /**
       * A code indicating that the action was a failure
       */
      ExitCode[ExitCode["Failure"] = 1] = "Failure";
  })(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
  //-----------------------------------------------------------------------
  // Variables
  //-----------------------------------------------------------------------
  /**
   * Sets env variable for this action and future actions in the job
   * @param name the name of the variable to set
   * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function exportVariable(name, val) {
      const convertedVal = utils.toCommandValue(val);
      process.env[name] = convertedVal;
      const filePath = process.env['GITHUB_ENV'] || '';
      if (filePath) {
          const delimiter = '_GitHubActionsFileCommandDelimeter_';
          const commandValue = `${name}<<${delimiter}${os$1.EOL}${convertedVal}${os$1.EOL}${delimiter}`;
          fileCommand.issueCommand('ENV', commandValue);
      }
      else {
          command.issueCommand('set-env', { name }, convertedVal);
      }
  }
  exports.exportVariable = exportVariable;
  /**
   * Registers a secret which will get masked from logs
   * @param secret value of the secret
   */
  function setSecret(secret) {
      command.issueCommand('add-mask', {}, secret);
  }
  exports.setSecret = setSecret;
  /**
   * Prepends inputPath to the PATH (for this action and future actions)
   * @param inputPath
   */
  function addPath(inputPath) {
      const filePath = process.env['GITHUB_PATH'] || '';
      if (filePath) {
          fileCommand.issueCommand('PATH', inputPath);
      }
      else {
          command.issueCommand('add-path', {}, inputPath);
      }
      process.env['PATH'] = `${inputPath}${path$1.delimiter}${process.env['PATH']}`;
  }
  exports.addPath = addPath;
  /**
   * Gets the value of an input.  The value is also trimmed.
   *
   * @param     name     name of the input to get
   * @param     options  optional. See InputOptions.
   * @returns   string
   */
  function getInput(name, options) {
      const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
      if (options && options.required && !val) {
          throw new Error(`Input required and not supplied: ${name}`);
      }
      return val.trim();
  }
  exports.getInput = getInput;
  /**
   * Sets the value of an output.
   *
   * @param     name     name of the output to set
   * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function setOutput(name, value) {
      command.issueCommand('set-output', { name }, value);
  }
  exports.setOutput = setOutput;
  /**
   * Enables or disables the echoing of commands into stdout for the rest of the step.
   * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
   *
   */
  function setCommandEcho(enabled) {
      command.issue('echo', enabled ? 'on' : 'off');
  }
  exports.setCommandEcho = setCommandEcho;
  //-----------------------------------------------------------------------
  // Results
  //-----------------------------------------------------------------------
  /**
   * Sets the action status to failed.
   * When the action exits it will be with an exit code of 1
   * @param message add error issue message
   */
  function setFailed(message) {
      process.exitCode = ExitCode.Failure;
      error(message);
  }
  exports.setFailed = setFailed;
  //-----------------------------------------------------------------------
  // Logging Commands
  //-----------------------------------------------------------------------
  /**
   * Gets whether Actions Step Debug is on or not
   */
  function isDebug() {
      return process.env['RUNNER_DEBUG'] === '1';
  }
  exports.isDebug = isDebug;
  /**
   * Writes debug message to user log
   * @param message debug message
   */
  function debug(message) {
      command.issueCommand('debug', {}, message);
  }
  exports.debug = debug;
  /**
   * Adds an error issue
   * @param message error issue message. Errors will be converted to string via toString()
   */
  function error(message) {
      command.issue('error', message instanceof Error ? message.toString() : message);
  }
  exports.error = error;
  /**
   * Adds an warning issue
   * @param message warning issue message. Errors will be converted to string via toString()
   */
  function warning(message) {
      command.issue('warning', message instanceof Error ? message.toString() : message);
  }
  exports.warning = warning;
  /**
   * Writes info to log with console.log.
   * @param message info message
   */
  function info(message) {
      process.stdout.write(message + os$1.EOL);
  }
  exports.info = info;
  /**
   * Begin an output group.
   *
   * Output until the next `groupEnd` will be foldable in this group
   *
   * @param name The name of the output group
   */
  function startGroup(name) {
      command.issue('group', name);
  }
  exports.startGroup = startGroup;
  /**
   * End an output group.
   */
  function endGroup() {
      command.issue('endgroup');
  }
  exports.endGroup = endGroup;
  /**
   * Wrap an asynchronous function call in a group.
   *
   * Returns the same type as the function itself.
   *
   * @param name The name of the group
   * @param fn The function to wrap in the group
   */
  function group(name, fn) {
      return __awaiter(this, void 0, void 0, function* () {
          startGroup(name);
          let result;
          try {
              result = yield fn();
          }
          finally {
              endGroup();
          }
          return result;
      });
  }
  exports.group = group;
  //-----------------------------------------------------------------------
  // Wrapper action state
  //-----------------------------------------------------------------------
  /**
   * Saves state for current action, the state can only be retrieved by this action's post job execution.
   *
   * @param     name     name of the state to store
   * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function saveState(name, value) {
      command.issueCommand('save-state', { name }, value);
  }
  exports.saveState = saveState;
  /**
   * Gets the value of an state set by this action's main execution.
   *
   * @param     name     name of the state to get
   * @returns   string
   */
  function getState(name) {
      return process.env[`STATE_${name}`] || '';
  }
  exports.getState = getState;
  
  });
  
  var core$1 = /*@__PURE__*/unwrapExports(core);
  
  var dist = createCommonjsModule(function (module, exports) {
  /// <reference lib="es2018"/>
  /// <reference lib="dom"/>
  /// <reference types="node"/>
  Object.defineProperty(exports, "__esModule", { value: true });
  const typedArrayTypeNames = [
      'Int8Array',
      'Uint8Array',
      'Uint8ClampedArray',
      'Int16Array',
      'Uint16Array',
      'Int32Array',
      'Uint32Array',
      'Float32Array',
      'Float64Array',
      'BigInt64Array',
      'BigUint64Array'
  ];
  function isTypedArrayName(name) {
      return typedArrayTypeNames.includes(name);
  }
  const objectTypeNames = [
      'Function',
      'Generator',
      'AsyncGenerator',
      'GeneratorFunction',
      'AsyncGeneratorFunction',
      'AsyncFunction',
      'Observable',
      'Array',
      'Buffer',
      'Object',
      'RegExp',
      'Date',
      'Error',
      'Map',
      'Set',
      'WeakMap',
      'WeakSet',
      'ArrayBuffer',
      'SharedArrayBuffer',
      'DataView',
      'Promise',
      'URL',
      'HTMLElement',
      ...typedArrayTypeNames
  ];
  function isObjectTypeName(name) {
      return objectTypeNames.includes(name);
  }
  const primitiveTypeNames = [
      'null',
      'undefined',
      'string',
      'number',
      'bigint',
      'boolean',
      'symbol'
  ];
  function isPrimitiveTypeName(name) {
      return primitiveTypeNames.includes(name);
  }
  // eslint-disable-next-line @typescript-eslint/ban-types
  function isOfType(type) {
      return (value) => typeof value === type;
  }
  const { toString } = Object.prototype;
  const getObjectType = (value) => {
      const objectTypeName = toString.call(value).slice(8, -1);
      if (/HTML\w+Element/.test(objectTypeName) && is.domElement(value)) {
          return 'HTMLElement';
      }
      if (isObjectTypeName(objectTypeName)) {
          return objectTypeName;
      }
      return undefined;
  };
  const isObjectOfType = (type) => (value) => getObjectType(value) === type;
  function is(value) {
      if (value === null) {
          return 'null';
      }
      switch (typeof value) {
          case 'undefined':
              return 'undefined';
          case 'string':
              return 'string';
          case 'number':
              return 'number';
          case 'boolean':
              return 'boolean';
          case 'function':
              return 'Function';
          case 'bigint':
              return 'bigint';
          case 'symbol':
              return 'symbol';
      }
      if (is.observable(value)) {
          return 'Observable';
      }
      if (is.array(value)) {
          return 'Array';
      }
      if (is.buffer(value)) {
          return 'Buffer';
      }
      const tagType = getObjectType(value);
      if (tagType) {
          return tagType;
      }
      if (value instanceof String || value instanceof Boolean || value instanceof Number) {
          throw new TypeError('Please don\'t use object wrappers for primitive types');
      }
      return 'Object';
  }
  is.undefined = isOfType('undefined');
  is.string = isOfType('string');
  const isNumberType = isOfType('number');
  is.number = (value) => isNumberType(value) && !is.nan(value);
  is.bigint = isOfType('bigint');
  // eslint-disable-next-line @typescript-eslint/ban-types
  is.function_ = isOfType('function');
  is.null_ = (value) => value === null;
  is.class_ = (value) => is.function_(value) && value.toString().startsWith('class ');
  is.boolean = (value) => value === true || value === false;
  is.symbol = isOfType('symbol');
  is.numericString = (value) => is.string(value) && !is.emptyStringOrWhitespace(value) && !Number.isNaN(Number(value));
  is.array = (value, assertion) => {
      if (!Array.isArray(value)) {
          return false;
      }
      if (!is.function_(assertion)) {
          return true;
      }
      return value.every(assertion);
  };
  is.buffer = (value) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = value) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.isBuffer) === null || _c === void 0 ? void 0 : _c.call(_b, value)) !== null && _d !== void 0 ? _d : false; };
  is.nullOrUndefined = (value) => is.null_(value) || is.undefined(value);
  is.object = (value) => !is.null_(value) && (typeof value === 'object' || is.function_(value));
  is.iterable = (value) => { var _a; return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.iterator]); };
  is.asyncIterable = (value) => { var _a; return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.asyncIterator]); };
  is.generator = (value) => is.iterable(value) && is.function_(value.next) && is.function_(value.throw);
  is.asyncGenerator = (value) => is.asyncIterable(value) && is.function_(value.next) && is.function_(value.throw);
  is.nativePromise = (value) => isObjectOfType('Promise')(value);
  const hasPromiseAPI = (value) => {
      var _a, _b;
      return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a.then) &&
          is.function_((_b = value) === null || _b === void 0 ? void 0 : _b.catch);
  };
  is.promise = (value) => is.nativePromise(value) || hasPromiseAPI(value);
  is.generatorFunction = isObjectOfType('GeneratorFunction');
  is.asyncGeneratorFunction = (value) => getObjectType(value) === 'AsyncGeneratorFunction';
  is.asyncFunction = (value) => getObjectType(value) === 'AsyncFunction';
  // eslint-disable-next-line no-prototype-builtins, @typescript-eslint/ban-types
  is.boundFunction = (value) => is.function_(value) && !value.hasOwnProperty('prototype');
  is.regExp = isObjectOfType('RegExp');
  is.date = isObjectOfType('Date');
  is.error = isObjectOfType('Error');
  is.map = (value) => isObjectOfType('Map')(value);
  is.set = (value) => isObjectOfType('Set')(value);
  is.weakMap = (value) => isObjectOfType('WeakMap')(value);
  is.weakSet = (value) => isObjectOfType('WeakSet')(value);
  is.int8Array = isObjectOfType('Int8Array');
  is.uint8Array = isObjectOfType('Uint8Array');
  is.uint8ClampedArray = isObjectOfType('Uint8ClampedArray');
  is.int16Array = isObjectOfType('Int16Array');
  is.uint16Array = isObjectOfType('Uint16Array');
  is.int32Array = isObjectOfType('Int32Array');
  is.uint32Array = isObjectOfType('Uint32Array');
  is.float32Array = isObjectOfType('Float32Array');
  is.float64Array = isObjectOfType('Float64Array');
  is.bigInt64Array = isObjectOfType('BigInt64Array');
  is.bigUint64Array = isObjectOfType('BigUint64Array');
  is.arrayBuffer = isObjectOfType('ArrayBuffer');
  is.sharedArrayBuffer = isObjectOfType('SharedArrayBuffer');
  is.dataView = isObjectOfType('DataView');
  is.directInstanceOf = (instance, class_) => Object.getPrototypeOf(instance) === class_.prototype;
  is.urlInstance = (value) => isObjectOfType('URL')(value);
  is.urlString = (value) => {
      if (!is.string(value)) {
          return false;
      }
      try {
          new URL(value); // eslint-disable-line no-new
          return true;
      }
      catch (_a) {
          return false;
      }
  };
  // TODO: Use the `not` operator with a type guard here when it's available.
  // Example: `is.truthy = (value: unknown): value is (not false | not 0 | not '' | not undefined | not null) => Boolean(value);`
  is.truthy = (value) => Boolean(value);
  // Example: `is.falsy = (value: unknown): value is (not true | 0 | '' | undefined | null) => Boolean(value);`
  is.falsy = (value) => !value;
  is.nan = (value) => Number.isNaN(value);
  is.primitive = (value) => is.null_(value) || isPrimitiveTypeName(typeof value);
  is.integer = (value) => Number.isInteger(value);
  is.safeInteger = (value) => Number.isSafeInteger(value);
  is.plainObject = (value) => {
      // From: https://github.com/sindresorhus/is-plain-obj/blob/master/index.js
      if (toString.call(value) !== '[object Object]') {
          return false;
      }
      const prototype = Object.getPrototypeOf(value);
      return prototype === null || prototype === Object.getPrototypeOf({});
  };
  is.typedArray = (value) => isTypedArrayName(getObjectType(value));
  const isValidLength = (value) => is.safeInteger(value) && value >= 0;
  is.arrayLike = (value) => !is.nullOrUndefined(value) && !is.function_(value) && isValidLength(value.length);
  is.inRange = (value, range) => {
      if (is.number(range)) {
          return value >= Math.min(0, range) && value <= Math.max(range, 0);
      }
      if (is.array(range) && range.length === 2) {
          return value >= Math.min(...range) && value <= Math.max(...range);
      }
      throw new TypeError(`Invalid range: ${JSON.stringify(range)}`);
  };
  const NODE_TYPE_ELEMENT = 1;
  const DOM_PROPERTIES_TO_CHECK = [
      'innerHTML',
      'ownerDocument',
      'style',
      'attributes',
      'nodeValue'
  ];
  is.domElement = (value) => {
      return is.object(value) &&
          value.nodeType === NODE_TYPE_ELEMENT &&
          is.string(value.nodeName) &&
          !is.plainObject(value) &&
          DOM_PROPERTIES_TO_CHECK.every(property => property in value);
  };
  is.observable = (value) => {
      var _a, _b, _c, _d;
      if (!value) {
          return false;
      }
      // eslint-disable-next-line no-use-extend-native/no-use-extend-native
      if (value === ((_b = (_a = value)[Symbol.observable]) === null || _b === void 0 ? void 0 : _b.call(_a))) {
          return true;
      }
      if (value === ((_d = (_c = value)['@@observable']) === null || _d === void 0 ? void 0 : _d.call(_c))) {
          return true;
      }
      return false;
  };
  is.nodeStream = (value) => is.object(value) && is.function_(value.pipe) && !is.observable(value);
  is.infinite = (value) => value === Infinity || value === -Infinity;
  const isAbsoluteMod2 = (remainder) => (value) => is.integer(value) && Math.abs(value % 2) === remainder;
  is.evenInteger = isAbsoluteMod2(0);
  is.oddInteger = isAbsoluteMod2(1);
  is.emptyArray = (value) => is.array(value) && value.length === 0;
  is.nonEmptyArray = (value) => is.array(value) && value.length > 0;
  is.emptyString = (value) => is.string(value) && value.length === 0;
  // TODO: Use `not ''` when the `not` operator is available.
  is.nonEmptyString = (value) => is.string(value) && value.length > 0;
  const isWhiteSpaceString = (value) => is.string(value) && !/\S/.test(value);
  is.emptyStringOrWhitespace = (value) => is.emptyString(value) || isWhiteSpaceString(value);
  is.emptyObject = (value) => is.object(value) && !is.map(value) && !is.set(value) && Object.keys(value).length === 0;
  // TODO: Use `not` operator here to remove `Map` and `Set` from type guard:
  // - https://github.com/Microsoft/TypeScript/pull/29317
  is.nonEmptyObject = (value) => is.object(value) && !is.map(value) && !is.set(value) && Object.keys(value).length > 0;
  is.emptySet = (value) => is.set(value) && value.size === 0;
  is.nonEmptySet = (value) => is.set(value) && value.size > 0;
  is.emptyMap = (value) => is.map(value) && value.size === 0;
  is.nonEmptyMap = (value) => is.map(value) && value.size > 0;
  const predicateOnArray = (method, predicate, values) => {
      if (!is.function_(predicate)) {
          throw new TypeError(`Invalid predicate: ${JSON.stringify(predicate)}`);
      }
      if (values.length === 0) {
          throw new TypeError('Invalid number of values');
      }
      return method.call(values, predicate);
  };
  is.any = (predicate, ...values) => {
      const predicates = is.array(predicate) ? predicate : [predicate];
      return predicates.some(singlePredicate => predicateOnArray(Array.prototype.some, singlePredicate, values));
  };
  is.all = (predicate, ...values) => predicateOnArray(Array.prototype.every, predicate, values);
  const assertType = (condition, description, value) => {
      if (!condition) {
          throw new TypeError(`Expected value which is \`${description}\`, received value of type \`${is(value)}\`.`);
      }
  };
  exports.assert = {
      // Unknowns.
      undefined: (value) => assertType(is.undefined(value), 'undefined', value),
      string: (value) => assertType(is.string(value), 'string', value),
      number: (value) => assertType(is.number(value), 'number', value),
      bigint: (value) => assertType(is.bigint(value), 'bigint', value),
      // eslint-disable-next-line @typescript-eslint/ban-types
      function_: (value) => assertType(is.function_(value), 'Function', value),
      null_: (value) => assertType(is.null_(value), 'null', value),
      class_: (value) => assertType(is.class_(value), "Class" /* class_ */, value),
      boolean: (value) => assertType(is.boolean(value), 'boolean', value),
      symbol: (value) => assertType(is.symbol(value), 'symbol', value),
      numericString: (value) => assertType(is.numericString(value), "string with a number" /* numericString */, value),
      array: (value, assertion) => {
          const assert = assertType;
          assert(is.array(value), 'Array', value);
          if (assertion) {
              value.forEach(assertion);
          }
      },
      buffer: (value) => assertType(is.buffer(value), 'Buffer', value),
      nullOrUndefined: (value) => assertType(is.nullOrUndefined(value), "null or undefined" /* nullOrUndefined */, value),
      object: (value) => assertType(is.object(value), 'Object', value),
      iterable: (value) => assertType(is.iterable(value), "Iterable" /* iterable */, value),
      asyncIterable: (value) => assertType(is.asyncIterable(value), "AsyncIterable" /* asyncIterable */, value),
      generator: (value) => assertType(is.generator(value), 'Generator', value),
      asyncGenerator: (value) => assertType(is.asyncGenerator(value), 'AsyncGenerator', value),
      nativePromise: (value) => assertType(is.nativePromise(value), "native Promise" /* nativePromise */, value),
      promise: (value) => assertType(is.promise(value), 'Promise', value),
      generatorFunction: (value) => assertType(is.generatorFunction(value), 'GeneratorFunction', value),
      asyncGeneratorFunction: (value) => assertType(is.asyncGeneratorFunction(value), 'AsyncGeneratorFunction', value),
      // eslint-disable-next-line @typescript-eslint/ban-types
      asyncFunction: (value) => assertType(is.asyncFunction(value), 'AsyncFunction', value),
      // eslint-disable-next-line @typescript-eslint/ban-types
      boundFunction: (value) => assertType(is.boundFunction(value), 'Function', value),
      regExp: (value) => assertType(is.regExp(value), 'RegExp', value),
      date: (value) => assertType(is.date(value), 'Date', value),
      error: (value) => assertType(is.error(value), 'Error', value),
      map: (value) => assertType(is.map(value), 'Map', value),
      set: (value) => assertType(is.set(value), 'Set', value),
      weakMap: (value) => assertType(is.weakMap(value), 'WeakMap', value),
      weakSet: (value) => assertType(is.weakSet(value), 'WeakSet', value),
      int8Array: (value) => assertType(is.int8Array(value), 'Int8Array', value),
      uint8Array: (value) => assertType(is.uint8Array(value), 'Uint8Array', value),
      uint8ClampedArray: (value) => assertType(is.uint8ClampedArray(value), 'Uint8ClampedArray', value),
      int16Array: (value) => assertType(is.int16Array(value), 'Int16Array', value),
      uint16Array: (value) => assertType(is.uint16Array(value), 'Uint16Array', value),
      int32Array: (value) => assertType(is.int32Array(value), 'Int32Array', value),
      uint32Array: (value) => assertType(is.uint32Array(value), 'Uint32Array', value),
      float32Array: (value) => assertType(is.float32Array(value), 'Float32Array', value),
      float64Array: (value) => assertType(is.float64Array(value), 'Float64Array', value),
      bigInt64Array: (value) => assertType(is.bigInt64Array(value), 'BigInt64Array', value),
      bigUint64Array: (value) => assertType(is.bigUint64Array(value), 'BigUint64Array', value),
      arrayBuffer: (value) => assertType(is.arrayBuffer(value), 'ArrayBuffer', value),
      sharedArrayBuffer: (value) => assertType(is.sharedArrayBuffer(value), 'SharedArrayBuffer', value),
      dataView: (value) => assertType(is.dataView(value), 'DataView', value),
      urlInstance: (value) => assertType(is.urlInstance(value), 'URL', value),
      urlString: (value) => assertType(is.urlString(value), "string with a URL" /* urlString */, value),
      truthy: (value) => assertType(is.truthy(value), "truthy" /* truthy */, value),
      falsy: (value) => assertType(is.falsy(value), "falsy" /* falsy */, value),
      nan: (value) => assertType(is.nan(value), "NaN" /* nan */, value),
      primitive: (value) => assertType(is.primitive(value), "primitive" /* primitive */, value),
      integer: (value) => assertType(is.integer(value), "integer" /* integer */, value),
      safeInteger: (value) => assertType(is.safeInteger(value), "integer" /* safeInteger */, value),
      plainObject: (value) => assertType(is.plainObject(value), "plain object" /* plainObject */, value),
      typedArray: (value) => assertType(is.typedArray(value), "TypedArray" /* typedArray */, value),
      arrayLike: (value) => assertType(is.arrayLike(value), "array-like" /* arrayLike */, value),
      domElement: (value) => assertType(is.domElement(value), "HTMLElement" /* domElement */, value),
      observable: (value) => assertType(is.observable(value), 'Observable', value),
      nodeStream: (value) => assertType(is.nodeStream(value), "Node.js Stream" /* nodeStream */, value),
      infinite: (value) => assertType(is.infinite(value), "infinite number" /* infinite */, value),
      emptyArray: (value) => assertType(is.emptyArray(value), "empty array" /* emptyArray */, value),
      nonEmptyArray: (value) => assertType(is.nonEmptyArray(value), "non-empty array" /* nonEmptyArray */, value),
      emptyString: (value) => assertType(is.emptyString(value), "empty string" /* emptyString */, value),
      nonEmptyString: (value) => assertType(is.nonEmptyString(value), "non-empty string" /* nonEmptyString */, value),
      emptyStringOrWhitespace: (value) => assertType(is.emptyStringOrWhitespace(value), "empty string or whitespace" /* emptyStringOrWhitespace */, value),
      emptyObject: (value) => assertType(is.emptyObject(value), "empty object" /* emptyObject */, value),
      nonEmptyObject: (value) => assertType(is.nonEmptyObject(value), "non-empty object" /* nonEmptyObject */, value),
      emptySet: (value) => assertType(is.emptySet(value), "empty set" /* emptySet */, value),
      nonEmptySet: (value) => assertType(is.nonEmptySet(value), "non-empty set" /* nonEmptySet */, value),
      emptyMap: (value) => assertType(is.emptyMap(value), "empty map" /* emptyMap */, value),
      nonEmptyMap: (value) => assertType(is.nonEmptyMap(value), "non-empty map" /* nonEmptyMap */, value),
      // Numbers.
      evenInteger: (value) => assertType(is.evenInteger(value), "even integer" /* evenInteger */, value),
      oddInteger: (value) => assertType(is.oddInteger(value), "odd integer" /* oddInteger */, value),
      // Two arguments.
      directInstanceOf: (instance, class_) => assertType(is.directInstanceOf(instance, class_), "T" /* directInstanceOf */, instance),
      inRange: (value, range) => assertType(is.inRange(value, range), "in range" /* inRange */, value),
      // Variadic functions.
      any: (predicate, ...values) => assertType(is.any(predicate, ...values), "predicate returns truthy for any value" /* any */, values),
      all: (predicate, ...values) => assertType(is.all(predicate, ...values), "predicate returns truthy for all values" /* all */, values)
  };
  // Some few keywords are reserved, but we'll populate them for Node.js users
  // See https://github.com/Microsoft/TypeScript/issues/2536
  Object.defineProperties(is, {
      class: {
          value: is.class_
      },
      function: {
          value: is.function_
      },
      null: {
          value: is.null_
      }
  });
  Object.defineProperties(exports.assert, {
      class: {
          value: exports.assert.class_
      },
      function: {
          value: exports.assert.function_
      },
      null: {
          value: exports.assert.null_
      }
  });
  exports.default = is;
  // For CommonJS default export support
  module.exports = is;
  module.exports.default = is;
  module.exports.assert = exports.assert;
  });
  
  class CancelError extends Error {
  	constructor(reason) {
  		super(reason || 'Promise was canceled');
  		this.name = 'CancelError';
  	}
  
  	get isCanceled() {
  		return true;
  	}
  }
  
  class PCancelable {
  	static fn(userFn) {
  		return (...arguments_) => {
  			return new PCancelable((resolve, reject, onCancel) => {
  				arguments_.push(onCancel);
  				// eslint-disable-next-line promise/prefer-await-to-then
  				userFn(...arguments_).then(resolve, reject);
  			});
  		};
  	}
  
  	constructor(executor) {
  		this._cancelHandlers = [];
  		this._isPending = true;
  		this._isCanceled = false;
  		this._rejectOnCancel = true;
  
  		this._promise = new Promise((resolve, reject) => {
  			this._reject = reject;
  
  			const onResolve = value => {
  				this._isPending = false;
  				resolve(value);
  			};
  
  			const onReject = error => {
  				this._isPending = false;
  				reject(error);
  			};
  
  			const onCancel = handler => {
  				if (!this._isPending) {
  					throw new Error('The `onCancel` handler was attached after the promise settled.');
  				}
  
  				this._cancelHandlers.push(handler);
  			};
  
  			Object.defineProperties(onCancel, {
  				shouldReject: {
  					get: () => this._rejectOnCancel,
  					set: boolean => {
  						this._rejectOnCancel = boolean;
  					}
  				}
  			});
  
  			return executor(onResolve, onReject, onCancel);
  		});
  	}
  
  	then(onFulfilled, onRejected) {
  		// eslint-disable-next-line promise/prefer-await-to-then
  		return this._promise.then(onFulfilled, onRejected);
  	}
  
  	catch(onRejected) {
  		return this._promise.catch(onRejected);
  	}
  
  	finally(onFinally) {
  		return this._promise.finally(onFinally);
  	}
  
  	cancel(reason) {
  		if (!this._isPending || this._isCanceled) {
  			return;
  		}
  
  		if (this._cancelHandlers.length > 0) {
  			try {
  				for (const handler of this._cancelHandlers) {
  					handler();
  				}
  			} catch (error) {
  				this._reject(error);
  			}
  		}
  
  		this._isCanceled = true;
  		if (this._rejectOnCancel) {
  			this._reject(new CancelError(reason));
  		}
  	}
  
  	get isCanceled() {
  		return this._isCanceled;
  	}
  }
  
  Object.setPrototypeOf(PCancelable.prototype, Promise.prototype);
  
  var pCancelable = PCancelable;
  var CancelError_1 = CancelError;
  pCancelable.CancelError = CancelError_1;
  
  var source = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  const deferToConnect = (socket, fn) => {
      let listeners;
      if (typeof fn === 'function') {
          const connect = fn;
          listeners = { connect };
      }
      else {
          listeners = fn;
      }
      const hasConnectListener = typeof listeners.connect === 'function';
      const hasSecureConnectListener = typeof listeners.secureConnect === 'function';
      const hasCloseListener = typeof listeners.close === 'function';
      const onConnect = () => {
          if (hasConnectListener) {
              listeners.connect();
          }
          if (socket instanceof tls.TLSSocket && hasSecureConnectListener) {
              if (socket.authorized) {
                  listeners.secureConnect();
              }
              else if (!socket.authorizationError) {
                  socket.once('secureConnect', listeners.secureConnect);
              }
          }
          if (hasCloseListener) {
              socket.once('close', listeners.close);
          }
      };
      if (socket.writable && !socket.connecting) {
          onConnect();
      }
      else if (socket.connecting) {
          socket.once('connect', onConnect);
      }
      else if (socket.destroyed && hasCloseListener) {
          listeners.close(socket._hadError);
      }
  };
  exports.default = deferToConnect;
  // For CommonJS default export support
  module.exports = deferToConnect;
  module.exports.default = deferToConnect;
  });
  
  var source$1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  const nodejsMajorVersion = Number(process.versions.node.split('.')[0]);
  const timer = (request) => {
      const timings = {
          start: Date.now(),
          socket: undefined,
          lookup: undefined,
          connect: undefined,
          secureConnect: undefined,
          upload: undefined,
          response: undefined,
          end: undefined,
          error: undefined,
          abort: undefined,
          phases: {
              wait: undefined,
              dns: undefined,
              tcp: undefined,
              tls: undefined,
              request: undefined,
              firstByte: undefined,
              download: undefined,
              total: undefined
          }
      };
      request.timings = timings;
      const handleError = (origin) => {
          const emit = origin.emit.bind(origin);
          origin.emit = (event, ...args) => {
              // Catches the `error` event
              if (event === 'error') {
                  timings.error = Date.now();
                  timings.phases.total = timings.error - timings.start;
                  origin.emit = emit;
              }
              // Saves the original behavior
              return emit(event, ...args);
          };
      };
      handleError(request);
      request.prependOnceListener('abort', () => {
          timings.abort = Date.now();
          // Let the `end` response event be responsible for setting the total phase,
          // unless the Node.js major version is >= 13.
          if (!timings.response || nodejsMajorVersion >= 13) {
              timings.phases.total = Date.now() - timings.start;
          }
      });
      const onSocket = (socket) => {
          timings.socket = Date.now();
          timings.phases.wait = timings.socket - timings.start;
          const lookupListener = () => {
              timings.lookup = Date.now();
              timings.phases.dns = timings.lookup - timings.socket;
          };
          socket.prependOnceListener('lookup', lookupListener);
          source.default(socket, {
              connect: () => {
                  timings.connect = Date.now();
                  if (timings.lookup === undefined) {
                      socket.removeListener('lookup', lookupListener);
                      timings.lookup = timings.connect;
                      timings.phases.dns = timings.lookup - timings.socket;
                  }
                  timings.phases.tcp = timings.connect - timings.lookup;
                  // This callback is called before flushing any data,
                  // so we don't need to set `timings.phases.request` here.
              },
              secureConnect: () => {
                  timings.secureConnect = Date.now();
                  timings.phases.tls = timings.secureConnect - timings.connect;
              }
          });
      };
      if (request.socket) {
          onSocket(request.socket);
      }
      else {
          request.prependOnceListener('socket', onSocket);
      }
      const onUpload = () => {
          var _a;
          timings.upload = Date.now();
          timings.phases.request = timings.upload - (_a = timings.secureConnect, (_a !== null && _a !== void 0 ? _a : timings.connect));
      };
      const writableFinished = () => {
          if (typeof request.writableFinished === 'boolean') {
              return request.writableFinished;
          }
          // Node.js doesn't have `request.writableFinished` property
          return request.finished && request.outputSize === 0 && (!request.socket || request.socket.writableLength === 0);
      };
      if (writableFinished()) {
          onUpload();
      }
      else {
          request.prependOnceListener('finish', onUpload);
      }
      request.prependOnceListener('response', (response) => {
          timings.response = Date.now();
          timings.phases.firstByte = timings.response - timings.upload;
          response.timings = timings;
          handleError(response);
          response.prependOnceListener('end', () => {
              timings.end = Date.now();
              timings.phases.download = timings.end - timings.response;
              timings.phases.total = timings.end - timings.start;
          });
      });
      return timings;
  };
  exports.default = timer;
  // For CommonJS default export support
  module.exports = timer;
  module.exports.default = timer;
  });
  
  const {
  	V4MAPPED,
  	ADDRCONFIG,
  	ALL,
  	promises: {
  		Resolver: AsyncResolver
  	},
  	lookup: dnsLookup
  } = dns;
  const {promisify} = util;
  
  
  const kCacheableLookupCreateConnection = Symbol('cacheableLookupCreateConnection');
  const kCacheableLookupInstance = Symbol('cacheableLookupInstance');
  const kExpires = Symbol('expires');
  
  const supportsALL = typeof ALL === 'number';
  
  const verifyAgent = agent => {
  	if (!(agent && typeof agent.createConnection === 'function')) {
  		throw new Error('Expected an Agent instance as the first argument');
  	}
  };
  
  const map4to6 = entries => {
  	for (const entry of entries) {
  		if (entry.family === 6) {
  			continue;
  		}
  
  		entry.address = `::ffff:${entry.address}`;
  		entry.family = 6;
  	}
  };
  
  const getIfaceInfo = () => {
  	let has4 = false;
  	let has6 = false;
  
  	for (const device of Object.values(os.networkInterfaces())) {
  		for (const iface of device) {
  			if (iface.internal) {
  				continue;
  			}
  
  			if (iface.family === 'IPv6') {
  				has6 = true;
  			} else {
  				has4 = true;
  			}
  
  			if (has4 && has6) {
  				return {has4, has6};
  			}
  		}
  	}
  
  	return {has4, has6};
  };
  
  const isIterable = map => {
  	return Symbol.iterator in map;
  };
  
  const ttl = {ttl: true};
  const all = {all: true};
  
  class CacheableLookup {
  	constructor({
  		cache = new Map(),
  		maxTtl = Infinity,
  		fallbackDuration = 3600,
  		errorTtl = 0.15,
  		resolver = new AsyncResolver(),
  		lookup = dnsLookup
  	} = {}) {
  		this.maxTtl = maxTtl;
  		this.errorTtl = errorTtl;
  
  		this._cache = cache;
  		this._resolver = resolver;
  		this._dnsLookup = promisify(lookup);
  
  		if (this._resolver instanceof AsyncResolver) {
  			this._resolve4 = this._resolver.resolve4.bind(this._resolver);
  			this._resolve6 = this._resolver.resolve6.bind(this._resolver);
  		} else {
  			this._resolve4 = promisify(this._resolver.resolve4.bind(this._resolver));
  			this._resolve6 = promisify(this._resolver.resolve6.bind(this._resolver));
  		}
  
  		this._iface = getIfaceInfo();
  
  		this._pending = {};
  		this._nextRemovalTime = false;
  		this._hostnamesToFallback = new Set();
  
  		if (fallbackDuration < 1) {
  			this._fallback = false;
  		} else {
  			this._fallback = true;
  
  			const interval = setInterval(() => {
  				this._hostnamesToFallback.clear();
  			}, fallbackDuration * 1000);
  
  			/* istanbul ignore next: There is no `interval.unref()` when running inside an Electron renderer */
  			if (interval.unref) {
  				interval.unref();
  			}
  		}
  
  		this.lookup = this.lookup.bind(this);
  		this.lookupAsync = this.lookupAsync.bind(this);
  	}
  
  	set servers(servers) {
  		this.clear();
  
  		this._resolver.setServers(servers);
  	}
  
  	get servers() {
  		return this._resolver.getServers();
  	}
  
  	lookup(hostname, options, callback) {
  		if (typeof options === 'function') {
  			callback = options;
  			options = {};
  		} else if (typeof options === 'number') {
  			options = {
  				family: options
  			};
  		}
  
  		if (!callback) {
  			throw new Error('Callback must be a function.');
  		}
  
  		// eslint-disable-next-line promise/prefer-await-to-then
  		this.lookupAsync(hostname, options).then(result => {
  			if (options.all) {
  				callback(null, result);
  			} else {
  				callback(null, result.address, result.family, result.expires, result.ttl);
  			}
  		}, callback);
  	}
  
  	async lookupAsync(hostname, options = {}) {
  		if (typeof options === 'number') {
  			options = {
  				family: options
  			};
  		}
  
  		let cached = await this.query(hostname);
  
  		if (options.family === 6) {
  			const filtered = cached.filter(entry => entry.family === 6);
  
  			if (options.hints & V4MAPPED) {
  				if ((supportsALL && options.hints & ALL) || filtered.length === 0) {
  					map4to6(cached);
  				} else {
  					cached = filtered;
  				}
  			} else {
  				cached = filtered;
  			}
  		} else if (options.family === 4) {
  			cached = cached.filter(entry => entry.family === 4);
  		}
  
  		if (options.hints & ADDRCONFIG) {
  			const {_iface} = this;
  			cached = cached.filter(entry => entry.family === 6 ? _iface.has6 : _iface.has4);
  		}
  
  		if (cached.length === 0) {
  			const error = new Error(`cacheableLookup ENOTFOUND ${hostname}`);
  			error.code = 'ENOTFOUND';
  			error.hostname = hostname;
  
  			throw error;
  		}
  
  		if (options.all) {
  			return cached;
  		}
  
  		return cached[0];
  	}
  
  	async query(hostname) {
  		let cached = await this._cache.get(hostname);
  
  		if (!cached) {
  			const pending = this._pending[hostname];
  
  			if (pending) {
  				cached = await pending;
  			} else {
  				const newPromise = this.queryAndCache(hostname);
  				this._pending[hostname] = newPromise;
  
  				cached = await newPromise;
  			}
  		}
  
  		cached = cached.map(entry => {
  			return {...entry};
  		});
  
  		return cached;
  	}
  
  	async _resolve(hostname) {
  		const wrap = async promise => {
  			try {
  				return await promise;
  			} catch (error) {
  				if (error.code === 'ENODATA' || error.code === 'ENOTFOUND') {
  					return [];
  				}
  
  				throw error;
  			}
  		};
  
  		// ANY is unsafe as it doesn't trigger new queries in the underlying server.
  		const [A, AAAA] = await Promise.all([
  			this._resolve4(hostname, ttl),
  			this._resolve6(hostname, ttl)
  		].map(promise => wrap(promise)));
  
  		let aTtl = 0;
  		let aaaaTtl = 0;
  		let cacheTtl = 0;
  
  		const now = Date.now();
  
  		for (const entry of A) {
  			entry.family = 4;
  			entry.expires = now + (entry.ttl * 1000);
  
  			aTtl = Math.max(aTtl, entry.ttl);
  		}
  
  		for (const entry of AAAA) {
  			entry.family = 6;
  			entry.expires = now + (entry.ttl * 1000);
  
  			aaaaTtl = Math.max(aaaaTtl, entry.ttl);
  		}
  
  		if (A.length > 0) {
  			if (AAAA.length > 0) {
  				cacheTtl = Math.min(aTtl, aaaaTtl);
  			} else {
  				cacheTtl = aTtl;
  			}
  		} else {
  			cacheTtl = aaaaTtl;
  		}
  
  		return {
  			entries: [
  				...A,
  				...AAAA
  			],
  			cacheTtl
  		};
  	}
  
  	async _lookup(hostname) {
  		try {
  			const entries = await this._dnsLookup(hostname, {
  				all: true
  			});
  
  			return {
  				entries,
  				cacheTtl: 0
  			};
  		} catch (_) {
  			return {
  				entries: [],
  				cacheTtl: 0
  			};
  		}
  	}
  
  	async _set(hostname, data, cacheTtl) {
  		if (this.maxTtl > 0 && cacheTtl > 0) {
  			cacheTtl = Math.min(cacheTtl, this.maxTtl) * 1000;
  			data[kExpires] = Date.now() + cacheTtl;
  
  			try {
  				await this._cache.set(hostname, data, cacheTtl);
  			} catch (error) {
  				this.lookupAsync = async () => {
  					const cacheError = new Error('Cache Error. Please recreate the CacheableLookup instance.');
  					cacheError.cause = error;
  
  					throw cacheError;
  				};
  			}
  
  			if (isIterable(this._cache)) {
  				this._tick(cacheTtl);
  			}
  		}
  	}
  
  	async queryAndCache(hostname) {
  		if (this._hostnamesToFallback.has(hostname)) {
  			return this._dnsLookup(hostname, all);
  		}
  
  		try {
  			let query = await this._resolve(hostname);
  
  			if (query.entries.length === 0 && this._fallback) {
  				query = await this._lookup(hostname);
  
  				if (query.entries.length !== 0) {
  					// Use `dns.lookup(...)` for that particular hostname
  					this._hostnamesToFallback.add(hostname);
  				}
  			}
  
  			const cacheTtl = query.entries.length === 0 ? this.errorTtl : query.cacheTtl;
  			await this._set(hostname, query.entries, cacheTtl);
  
  			delete this._pending[hostname];
  
  			return query.entries;
  		} catch (error) {
  			delete this._pending[hostname];
  
  			throw error;
  		}
  	}
  
  	_tick(ms) {
  		const nextRemovalTime = this._nextRemovalTime;
  
  		if (!nextRemovalTime || ms < nextRemovalTime) {
  			clearTimeout(this._removalTimeout);
  
  			this._nextRemovalTime = ms;
  
  			this._removalTimeout = setTimeout(() => {
  				this._nextRemovalTime = false;
  
  				let nextExpiry = Infinity;
  
  				const now = Date.now();
  
  				for (const [hostname, entries] of this._cache) {
  					const expires = entries[kExpires];
  
  					if (now >= expires) {
  						this._cache.delete(hostname);
  					} else if (expires < nextExpiry) {
  						nextExpiry = expires;
  					}
  				}
  
  				if (nextExpiry !== Infinity) {
  					this._tick(nextExpiry - now);
  				}
  			}, ms);
  
  			/* istanbul ignore next: There is no `timeout.unref()` when running inside an Electron renderer */
  			if (this._removalTimeout.unref) {
  				this._removalTimeout.unref();
  			}
  		}
  	}
  
  	install(agent) {
  		verifyAgent(agent);
  
  		if (kCacheableLookupCreateConnection in agent) {
  			throw new Error('CacheableLookup has been already installed');
  		}
  
  		agent[kCacheableLookupCreateConnection] = agent.createConnection;
  		agent[kCacheableLookupInstance] = this;
  
  		agent.createConnection = (options, callback) => {
  			if (!('lookup' in options)) {
  				options.lookup = this.lookup;
  			}
  
  			return agent[kCacheableLookupCreateConnection](options, callback);
  		};
  	}
  
  	uninstall(agent) {
  		verifyAgent(agent);
  
  		if (agent[kCacheableLookupCreateConnection]) {
  			if (agent[kCacheableLookupInstance] !== this) {
  				throw new Error('The agent is not owned by this CacheableLookup instance');
  			}
  
  			agent.createConnection = agent[kCacheableLookupCreateConnection];
  
  			delete agent[kCacheableLookupCreateConnection];
  			delete agent[kCacheableLookupInstance];
  		}
  	}
  
  	updateInterfaceInfo() {
  		const {_iface} = this;
  
  		this._iface = getIfaceInfo();
  
  		if ((_iface.has4 && !this._iface.has4) || (_iface.has6 && !this._iface.has6)) {
  			this._cache.clear();
  		}
  	}
  
  	clear(hostname) {
  		if (hostname) {
  			this._cache.delete(hostname);
  			return;
  		}
  
  		this._cache.clear();
  	}
  }
  
  var source$2 = CacheableLookup;
  var _default = CacheableLookup;
  source$2.default = _default;
  
  // TODO: Use the `URL` global when targeting Node.js 10
  const URLParser = typeof URL === 'undefined' ? Url.URL : URL;
  
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
  const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain';
  const DATA_URL_DEFAULT_CHARSET = 'us-ascii';
  
  const testParameter = (name, filters) => {
  	return filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
  };
  
  const normalizeDataURL = (urlString, {stripHash}) => {
  	const parts = urlString.match(/^data:(.*?),(.*?)(?:#(.*))?$/);
  
  	if (!parts) {
  		throw new Error(`Invalid URL: ${urlString}`);
  	}
  
  	const mediaType = parts[1].split(';');
  	const body = parts[2];
  	const hash = stripHash ? '' : parts[3];
  
  	let base64 = false;
  
  	if (mediaType[mediaType.length - 1] === 'base64') {
  		mediaType.pop();
  		base64 = true;
  	}
  
  	// Lowercase MIME type
  	const mimeType = (mediaType.shift() || '').toLowerCase();
  	const attributes = mediaType
  		.map(attribute => {
  			let [key, value = ''] = attribute.split('=').map(string => string.trim());
  
  			// Lowercase `charset`
  			if (key === 'charset') {
  				value = value.toLowerCase();
  
  				if (value === DATA_URL_DEFAULT_CHARSET) {
  					return '';
  				}
  			}
  
  			return `${key}${value ? `=${value}` : ''}`;
  		})
  		.filter(Boolean);
  
  	const normalizedMediaType = [
  		...attributes
  	];
  
  	if (base64) {
  		normalizedMediaType.push('base64');
  	}
  
  	if (normalizedMediaType.length !== 0 || (mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE)) {
  		normalizedMediaType.unshift(mimeType);
  	}
  
  	return `data:${normalizedMediaType.join(';')},${base64 ? body.trim() : body}${hash ? `#${hash}` : ''}`;
  };
  
  const normalizeUrl = (urlString, options) => {
  	options = {
  		defaultProtocol: 'http:',
  		normalizeProtocol: true,
  		forceHttp: false,
  		forceHttps: false,
  		stripAuthentication: true,
  		stripHash: false,
  		stripWWW: true,
  		removeQueryParameters: [/^utm_\w+/i],
  		removeTrailingSlash: true,
  		removeDirectoryIndex: false,
  		sortQueryParameters: true,
  		...options
  	};
  
  	// TODO: Remove this at some point in the future
  	if (Reflect.has(options, 'normalizeHttps')) {
  		throw new Error('options.normalizeHttps is renamed to options.forceHttp');
  	}
  
  	if (Reflect.has(options, 'normalizeHttp')) {
  		throw new Error('options.normalizeHttp is renamed to options.forceHttps');
  	}
  
  	if (Reflect.has(options, 'stripFragment')) {
  		throw new Error('options.stripFragment is renamed to options.stripHash');
  	}
  
  	urlString = urlString.trim();
  
  	// Data URL
  	if (/^data:/i.test(urlString)) {
  		return normalizeDataURL(urlString, options);
  	}
  
  	const hasRelativeProtocol = urlString.startsWith('//');
  	const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
  
  	// Prepend protocol
  	if (!isRelativeUrl) {
  		urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
  	}
  
  	const urlObj = new URLParser(urlString);
  
  	if (options.forceHttp && options.forceHttps) {
  		throw new Error('The `forceHttp` and `forceHttps` options cannot be used together');
  	}
  
  	if (options.forceHttp && urlObj.protocol === 'https:') {
  		urlObj.protocol = 'http:';
  	}
  
  	if (options.forceHttps && urlObj.protocol === 'http:') {
  		urlObj.protocol = 'https:';
  	}
  
  	// Remove auth
  	if (options.stripAuthentication) {
  		urlObj.username = '';
  		urlObj.password = '';
  	}
  
  	// Remove hash
  	if (options.stripHash) {
  		urlObj.hash = '';
  	}
  
  	// Remove duplicate slashes if not preceded by a protocol
  	if (urlObj.pathname) {
  		// TODO: Use the following instead when targeting Node.js 10
  		// `urlObj.pathname = urlObj.pathname.replace(/(?<!https?:)\/{2,}/g, '/');`
  		urlObj.pathname = urlObj.pathname.replace(/((?!:).|^)\/{2,}/g, (_, p1) => {
  			if (/^(?!\/)/g.test(p1)) {
  				return `${p1}/`;
  			}
  
  			return '/';
  		});
  	}
  
  	// Decode URI octets
  	if (urlObj.pathname) {
  		urlObj.pathname = decodeURI(urlObj.pathname);
  	}
  
  	// Remove directory index
  	if (options.removeDirectoryIndex === true) {
  		options.removeDirectoryIndex = [/^index\.[a-z]+$/];
  	}
  
  	if (Array.isArray(options.removeDirectoryIndex) && options.removeDirectoryIndex.length > 0) {
  		let pathComponents = urlObj.pathname.split('/');
  		const lastComponent = pathComponents[pathComponents.length - 1];
  
  		if (testParameter(lastComponent, options.removeDirectoryIndex)) {
  			pathComponents = pathComponents.slice(0, pathComponents.length - 1);
  			urlObj.pathname = pathComponents.slice(1).join('/') + '/';
  		}
  	}
  
  	if (urlObj.hostname) {
  		// Remove trailing dot
  		urlObj.hostname = urlObj.hostname.replace(/\.$/, '');
  
  		// Remove `www.`
  		if (options.stripWWW && /^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(urlObj.hostname)) {
  			// Each label should be max 63 at length (min: 2).
  			// The extension should be max 5 at length (min: 2).
  			// Source: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
  			urlObj.hostname = urlObj.hostname.replace(/^www\./, '');
  		}
  	}
  
  	// Remove query unwanted parameters
  	if (Array.isArray(options.removeQueryParameters)) {
  		for (const key of [...urlObj.searchParams.keys()]) {
  			if (testParameter(key, options.removeQueryParameters)) {
  				urlObj.searchParams.delete(key);
  			}
  		}
  	}
  
  	// Sort query parameters
  	if (options.sortQueryParameters) {
  		urlObj.searchParams.sort();
  	}
  
  	if (options.removeTrailingSlash) {
  		urlObj.pathname = urlObj.pathname.replace(/\/$/, '');
  	}
  
  	// Take advantage of many of the Node `url` normalizations
  	urlString = urlObj.toString();
  
  	// Remove ending `/`
  	if ((options.removeTrailingSlash || urlObj.pathname === '/') && urlObj.hash === '') {
  		urlString = urlString.replace(/\/$/, '');
  	}
  
  	// Restore relative protocol, if applicable
  	if (hasRelativeProtocol && !options.normalizeProtocol) {
  		urlString = urlString.replace(/^http:\/\//, '//');
  	}
  
  	// Remove http/https
  	if (options.stripProtocol) {
  		urlString = urlString.replace(/^(?:https?:)?\/\//, '');
  	}
  
  	return urlString;
  };
  
  var normalizeUrl_1 = normalizeUrl;
  // TODO: Remove this for the next major release
  var _default$1 = normalizeUrl;
  normalizeUrl_1.default = _default$1;
  
  // Returns a wrapper function that returns a wrapped callback
  // The wrapper function should do some stuff, and return a
  // presumably different callback function.
  // This makes sure that own properties are retained, so that
  // decorations and such are not lost along the way.
  var wrappy_1 = wrappy;
  function wrappy (fn, cb) {
    if (fn && cb) return wrappy(fn)(cb)
  
    if (typeof fn !== 'function')
      throw new TypeError('need wrapper function')
  
    Object.keys(fn).forEach(function (k) {
      wrapper[k] = fn[k];
    });
  
    return wrapper
  
    function wrapper() {
      var args = new Array(arguments.length);
      for (var i = 0; i < args.length; i++) {
        args[i] = arguments[i];
      }
      var ret = fn.apply(this, args);
      var cb = args[args.length-1];
      if (typeof ret === 'function' && ret !== cb) {
        Object.keys(cb).forEach(function (k) {
          ret[k] = cb[k];
        });
      }
      return ret
    }
  }
  
  var once_1 = wrappy_1(once);
  var strict = wrappy_1(onceStrict);
  
  once.proto = once(function () {
    Object.defineProperty(Function.prototype, 'once', {
      value: function () {
        return once(this)
      },
      configurable: true
    });
  
    Object.defineProperty(Function.prototype, 'onceStrict', {
      value: function () {
        return onceStrict(this)
      },
      configurable: true
    });
  });
  
  function once (fn) {
    var f = function () {
      if (f.called) return f.value
      f.called = true;
      return f.value = fn.apply(this, arguments)
    };
    f.called = false;
    return f
  }
  
  function onceStrict (fn) {
    var f = function () {
      if (f.called)
        throw new Error(f.onceError)
      f.called = true;
      return f.value = fn.apply(this, arguments)
    };
    var name = fn.name || 'Function wrapped with `once`';
    f.onceError = name + " shouldn't be called more than once";
    f.called = false;
    return f
  }
  once_1.strict = strict;
  
  var noop = function() {};
  
  var isRequest = function(stream) {
  	return stream.setHeader && typeof stream.abort === 'function';
  };
  
  var isChildProcess = function(stream) {
  	return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3
  };
  
  var eos = function(stream, opts, callback) {
  	if (typeof opts === 'function') return eos(stream, null, opts);
  	if (!opts) opts = {};
  
  	callback = once_1(callback || noop);
  
  	var ws = stream._writableState;
  	var rs = stream._readableState;
  	var readable = opts.readable || (opts.readable !== false && stream.readable);
  	var writable = opts.writable || (opts.writable !== false && stream.writable);
  	var cancelled = false;
  
  	var onlegacyfinish = function() {
  		if (!stream.writable) onfinish();
  	};
  
  	var onfinish = function() {
  		writable = false;
  		if (!readable) callback.call(stream);
  	};
  
  	var onend = function() {
  		readable = false;
  		if (!writable) callback.call(stream);
  	};
  
  	var onexit = function(exitCode) {
  		callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null);
  	};
  
  	var onerror = function(err) {
  		callback.call(stream, err);
  	};
  
  	var onclose = function() {
  		process.nextTick(onclosenexttick);
  	};
  
  	var onclosenexttick = function() {
  		if (cancelled) return;
  		if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close'));
  		if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close'));
  	};
  
  	var onrequest = function() {
  		stream.req.on('finish', onfinish);
  	};
  
  	if (isRequest(stream)) {
  		stream.on('complete', onfinish);
  		stream.on('abort', onclose);
  		if (stream.req) onrequest();
  		else stream.on('request', onrequest);
  	} else if (writable && !ws) { // legacy streams
  		stream.on('end', onlegacyfinish);
  		stream.on('close', onlegacyfinish);
  	}
  
  	if (isChildProcess(stream)) stream.on('exit', onexit);
  
  	stream.on('end', onend);
  	stream.on('finish', onfinish);
  	if (opts.error !== false) stream.on('error', onerror);
  	stream.on('close', onclose);
  
  	return function() {
  		cancelled = true;
  		stream.removeListener('complete', onfinish);
  		stream.removeListener('abort', onclose);
  		stream.removeListener('request', onrequest);
  		if (stream.req) stream.req.removeListener('finish', onfinish);
  		stream.removeListener('end', onlegacyfinish);
  		stream.removeListener('close', onlegacyfinish);
  		stream.removeListener('finish', onfinish);
  		stream.removeListener('exit', onexit);
  		stream.removeListener('end', onend);
  		stream.removeListener('error', onerror);
  		stream.removeListener('close', onclose);
  	};
  };
  
  var endOfStream = eos;
  
  // we only need fs to get the ReadStream and WriteStream prototypes
  
  var noop$1 = function () {};
  var ancient = /^v?\.0/.test(process.version);
  
  var isFn = function (fn) {
    return typeof fn === 'function'
  };
  
  var isFS = function (stream) {
    if (!ancient) return false // newer node version do not need to care about fs is a special way
    if (!fs) return false // browser
    return (stream instanceof (fs.ReadStream || noop$1) || stream instanceof (fs.WriteStream || noop$1)) && isFn(stream.close)
  };
  
  var isRequest$1 = function (stream) {
    return stream.setHeader && isFn(stream.abort)
  };
  
  var destroyer = function (stream, reading, writing, callback) {
    callback = once_1(callback);
  
    var closed = false;
    stream.on('close', function () {
      closed = true;
    });
  
    endOfStream(stream, {readable: reading, writable: writing}, function (err) {
      if (err) return callback(err)
      closed = true;
      callback();
    });
  
    var destroyed = false;
    return function (err) {
      if (closed) return
      if (destroyed) return
      destroyed = true;
  
      if (isFS(stream)) return stream.close(noop$1) // use close for fs streams to avoid fd leaks
      if (isRequest$1(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want
  
      if (isFn(stream.destroy)) return stream.destroy()
  
      callback(err || new Error('stream was destroyed'));
    }
  };
  
  var call = function (fn) {
    fn();
  };
  
  var pipe = function (from, to) {
    return from.pipe(to)
  };
  
  var pump = function () {
    var streams = Array.prototype.slice.call(arguments);
    var callback = isFn(streams[streams.length - 1] || noop$1) && streams.pop() || noop$1;
  
    if (Array.isArray(streams[0])) streams = streams[0];
    if (streams.length < 2) throw new Error('pump requires two streams per minimum')
  
    var error;
    var destroys = streams.map(function (stream, i) {
      var reading = i < streams.length - 1;
      var writing = i > 0;
      return destroyer(stream, reading, writing, function (err) {
        if (!error) error = err;
        if (err) destroys.forEach(call);
        if (reading) return
        destroys.forEach(call);
        callback(error);
      })
    });
  
    return streams.reduce(pipe)
  };
  
  var pump_1 = pump;
  
  const {PassThrough: PassThroughStream} = Stream;
  
  var bufferStream = options => {
  	options = {...options};
  
  	const {array} = options;
  	let {encoding} = options;
  	const isBuffer = encoding === 'buffer';
  	let objectMode = false;
  
  	if (array) {
  		objectMode = !(encoding || isBuffer);
  	} else {
  		encoding = encoding || 'utf8';
  	}
  
  	if (isBuffer) {
  		encoding = null;
  	}
  
  	const stream = new PassThroughStream({objectMode});
  
  	if (encoding) {
  		stream.setEncoding(encoding);
  	}
  
  	let length = 0;
  	const chunks = [];
  
  	stream.on('data', chunk => {
  		chunks.push(chunk);
  
  		if (objectMode) {
  			length = chunks.length;
  		} else {
  			length += chunk.length;
  		}
  	});
  
  	stream.getBufferedValue = () => {
  		if (array) {
  			return chunks;
  		}
  
  		return isBuffer ? Buffer.concat(chunks, length) : chunks.join('');
  	};
  
  	stream.getBufferedLength = () => length;
  
  	return stream;
  };
  
  const {constants: BufferConstants} = buffer$1;
  
  
  
  class MaxBufferError extends Error {
  	constructor() {
  		super('maxBuffer exceeded');
  		this.name = 'MaxBufferError';
  	}
  }
  
  async function getStream(inputStream, options) {
  	if (!inputStream) {
  		return Promise.reject(new Error('Expected a stream'));
  	}
  
  	options = {
  		maxBuffer: Infinity,
  		...options
  	};
  
  	const {maxBuffer} = options;
  
  	let stream;
  	await new Promise((resolve, reject) => {
  		const rejectPromise = error => {
  			// Don't retrieve an oversized buffer.
  			if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
  				error.bufferedData = stream.getBufferedValue();
  			}
  
  			reject(error);
  		};
  
  		stream = pump_1(inputStream, bufferStream(options), error => {
  			if (error) {
  				rejectPromise(error);
  				return;
  			}
  
  			resolve();
  		});
  
  		stream.on('data', () => {
  			if (stream.getBufferedLength() > maxBuffer) {
  				rejectPromise(new MaxBufferError());
  			}
  		});
  	});
  
  	return stream.getBufferedValue();
  }
  
  var getStream_1 = getStream;
  // TODO: Remove this for the next major release
  var _default$2 = getStream;
  var buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'});
  var array = (stream, options) => getStream(stream, {...options, array: true});
  var MaxBufferError_1 = MaxBufferError;
  getStream_1.default = _default$2;
  getStream_1.buffer = buffer;
  getStream_1.array = array;
  getStream_1.MaxBufferError = MaxBufferError_1;
  
  // rfc7231 6.1
  const statusCodeCacheableByDefault = new Set([
      200,
      203,
      204,
      206,
      300,
      301,
      404,
      405,
      410,
      414,
      501,
  ]);
  
  // This implementation does not understand partial responses (206)
  const understoodStatuses = new Set([
      200,
      203,
      204,
      300,
      301,
      302,
      303,
      307,
      308,
      404,
      405,
      410,
      414,
      501,
  ]);
  
  const errorStatusCodes = new Set([
      500,
      502,
      503, 
      504,
  ]);
  
  const hopByHopHeaders = {
      date: true, // included, because we add Age update Date
      connection: true,
      'keep-alive': true,
      'proxy-authenticate': true,
      'proxy-authorization': true,
      te: true,
      trailer: true,
      'transfer-encoding': true,
      upgrade: true,
  };
  
  const excludedFromRevalidationUpdate = {
      // Since the old body is reused, it doesn't make sense to change properties of the body
      'content-length': true,
      'content-encoding': true,
      'transfer-encoding': true,
      'content-range': true,
  };
  
  function toNumberOrZero(s) {
      const n = parseInt(s, 10);
      return isFinite(n) ? n : 0;
  }
  
  // RFC 5861
  function isErrorResponse(response) {
      // consider undefined response as faulty
      if(!response) {
          return true
      }
      return errorStatusCodes.has(response.status);
  }
  
  function parseCacheControl(header) {
      const cc = {};
      if (!header) return cc;
  
      // TODO: When there is more than one value present for a given directive (e.g., two Expires header fields, multiple Cache-Control: max-age directives),
      // the directive's value is considered invalid. Caches are encouraged to consider responses that have invalid freshness information to be stale
      const parts = header.trim().split(/\s*,\s*/); // TODO: lame parsing
      for (const part of parts) {
          const [k, v] = part.split(/\s*=\s*/, 2);
          cc[k] = v === undefined ? true : v.replace(/^"|"$/g, ''); // TODO: lame unquoting
      }
  
      return cc;
  }
  
  function formatCacheControl(cc) {
      let parts = [];
      for (const k in cc) {
          const v = cc[k];
          parts.push(v === true ? k : k + '=' + v);
      }
      if (!parts.length) {
          return undefined;
      }
      return parts.join(', ');
  }
  
  var httpCacheSemantics = class CachePolicy {
      constructor(
          req,
          res,
          {
              shared,
              cacheHeuristic,
              immutableMinTimeToLive,
              ignoreCargoCult,
              _fromObject,
          } = {}
      ) {
          if (_fromObject) {
              this._fromObject(_fromObject);
              return;
          }
  
          if (!res || !res.headers) {
              throw Error('Response headers missing');
          }
          this._assertRequestHasHeaders(req);
  
          this._responseTime = this.now();
          this._isShared = shared !== false;
          this._cacheHeuristic =
              undefined !== cacheHeuristic ? cacheHeuristic : 0.1; // 10% matches IE
          this._immutableMinTtl =
              undefined !== immutableMinTimeToLive
                  ? immutableMinTimeToLive
                  : 24 * 3600 * 1000;
  
          this._status = 'status' in res ? res.status : 200;
          this._resHeaders = res.headers;
          this._rescc = parseCacheControl(res.headers['cache-control']);
          this._method = 'method' in req ? req.method : 'GET';
          this._url = req.url;
          this._host = req.headers.host;
          this._noAuthorization = !req.headers.authorization;
          this._reqHeaders = res.headers.vary ? req.headers : null; // Don't keep all request headers if they won't be used
          this._reqcc = parseCacheControl(req.headers['cache-control']);
  
          // Assume that if someone uses legacy, non-standard uncecessary options they don't understand caching,
          // so there's no point stricly adhering to the blindly copy&pasted directives.
          if (
              ignoreCargoCult &&
              'pre-check' in this._rescc &&
              'post-check' in this._rescc
          ) {
              delete this._rescc['pre-check'];
              delete this._rescc['post-check'];
              delete this._rescc['no-cache'];
              delete this._rescc['no-store'];
              delete this._rescc['must-revalidate'];
              this._resHeaders = Object.assign({}, this._resHeaders, {
                  'cache-control': formatCacheControl(this._rescc),
              });
              delete this._resHeaders.expires;
              delete this._resHeaders.pragma;
          }
  
          // When the Cache-Control header field is not present in a request, caches MUST consider the no-cache request pragma-directive
          // as having the same effect as if "Cache-Control: no-cache" were present (see Section 5.2.1).
          if (
              res.headers['cache-control'] == null &&
              /no-cache/.test(res.headers.pragma)
          ) {
              this._rescc['no-cache'] = true;
          }
      }
  
      now() {
          return Date.now();
      }
  
      storable() {
          // The "no-store" request directive indicates that a cache MUST NOT store any part of either this request or any response to it.
          return !!(
              !this._reqcc['no-store'] &&
              // A cache MUST NOT store a response to any request, unless:
              // The request method is understood by the cache and defined as being cacheable, and
              ('GET' === this._method ||
                  'HEAD' === this._method ||
                  ('POST' === this._method && this._hasExplicitExpiration())) &&
              // the response status code is understood by the cache, and
              understoodStatuses.has(this._status) &&
              // the "no-store" cache directive does not appear in request or response header fields, and
              !this._rescc['no-store'] &&
              // the "private" response directive does not appear in the response, if the cache is shared, and
              (!this._isShared || !this._rescc.private) &&
              // the Authorization header field does not appear in the request, if the cache is shared,
              (!this._isShared ||
                  this._noAuthorization ||
                  this._allowsStoringAuthenticated()) &&
              // the response either:
              // contains an Expires header field, or
              (this._resHeaders.expires ||
                  // contains a max-age response directive, or
                  // contains a s-maxage response directive and the cache is shared, or
                  // contains a public response directive.
                  this._rescc['max-age'] ||
                  (this._isShared && this._rescc['s-maxage']) ||
                  this._rescc.public ||
                  // has a status code that is defined as cacheable by default
                  statusCodeCacheableByDefault.has(this._status))
          );
      }
  
      _hasExplicitExpiration() {
          // 4.2.1 Calculating Freshness Lifetime
          return (
              (this._isShared && this._rescc['s-maxage']) ||
              this._rescc['max-age'] ||
              this._resHeaders.expires
          );
      }
  
      _assertRequestHasHeaders(req) {
          if (!req || !req.headers) {
              throw Error('Request headers missing');
          }
      }
  
      satisfiesWithoutRevalidation(req) {
          this._assertRequestHasHeaders(req);
  
          // When presented with a request, a cache MUST NOT reuse a stored response, unless:
          // the presented request does not contain the no-cache pragma (Section 5.4), nor the no-cache cache directive,
          // unless the stored response is successfully validated (Section 4.3), and
          const requestCC = parseCacheControl(req.headers['cache-control']);
          if (requestCC['no-cache'] || /no-cache/.test(req.headers.pragma)) {
              return false;
          }
  
          if (requestCC['max-age'] && this.age() > requestCC['max-age']) {
              return false;
          }
  
          if (
              requestCC['min-fresh'] &&
              this.timeToLive() < 1000 * requestCC['min-fresh']
          ) {
              return false;
          }
  
          // the stored response is either:
          // fresh, or allowed to be served stale
          if (this.stale()) {
              const allowsStale =
                  requestCC['max-stale'] &&
                  !this._rescc['must-revalidate'] &&
                  (true === requestCC['max-stale'] ||
                      requestCC['max-stale'] > this.age() - this.maxAge());
              if (!allowsStale) {
                  return false;
              }
          }
  
          return this._requestMatches(req, false);
      }
  
      _requestMatches(req, allowHeadMethod) {
          // The presented effective request URI and that of the stored response match, and
          return (
              (!this._url || this._url === req.url) &&
              this._host === req.headers.host &&
              // the request method associated with the stored response allows it to be used for the presented request, and
              (!req.method ||
                  this._method === req.method ||
                  (allowHeadMethod && 'HEAD' === req.method)) &&
              // selecting header fields nominated by the stored response (if any) match those presented, and
              this._varyMatches(req)
          );
      }
  
      _allowsStoringAuthenticated() {
          //  following Cache-Control response directives (Section 5.2.2) have such an effect: must-revalidate, public, and s-maxage.
          return (
              this._rescc['must-revalidate'] ||
              this._rescc.public ||
              this._rescc['s-maxage']
          );
      }
  
      _varyMatches(req) {
          if (!this._resHeaders.vary) {
              return true;
          }
  
          // A Vary header field-value of "*" always fails to match
          if (this._resHeaders.vary === '*') {
              return false;
          }
  
          const fields = this._resHeaders.vary
              .trim()
              .toLowerCase()
              .split(/\s*,\s*/);
          for (const name of fields) {
              if (req.headers[name] !== this._reqHeaders[name]) return false;
          }
          return true;
      }
  
      _copyWithoutHopByHopHeaders(inHeaders) {
          const headers = {};
          for (const name in inHeaders) {
              if (hopByHopHeaders[name]) continue;
              headers[name] = inHeaders[name];
          }
          // 9.1.  Connection
          if (inHeaders.connection) {
              const tokens = inHeaders.connection.trim().split(/\s*,\s*/);
              for (const name of tokens) {
                  delete headers[name];
              }
          }
          if (headers.warning) {
              const warnings = headers.warning.split(/,/).filter(warning => {
                  return !/^\s*1[0-9][0-9]/.test(warning);
              });
              if (!warnings.length) {
                  delete headers.warning;
              } else {
                  headers.warning = warnings.join(',').trim();
              }
          }
          return headers;
      }
  
      responseHeaders() {
          const headers = this._copyWithoutHopByHopHeaders(this._resHeaders);
          const age = this.age();
  
          // A cache SHOULD generate 113 warning if it heuristically chose a freshness
          // lifetime greater than 24 hours and the response's age is greater than 24 hours.
          if (
              age > 3600 * 24 &&
              !this._hasExplicitExpiration() &&
              this.maxAge() > 3600 * 24
          ) {
              headers.warning =
                  (headers.warning ? `${headers.warning}, ` : '') +
                  '113 - "rfc7234 5.5.4"';
          }
          headers.age = `${Math.round(age)}`;
          headers.date = new Date(this.now()).toUTCString();
          return headers;
      }
  
      /**
       * Value of the Date response header or current time if Date was invalid
       * @return timestamp
       */
      date() {
          const serverDate = Date.parse(this._resHeaders.date);
          if (isFinite(serverDate)) {
              return serverDate;
          }
          return this._responseTime;
      }
  
      /**
       * Value of the Age header, in seconds, updated for the current time.
       * May be fractional.
       *
       * @return Number
       */
      age() {
          let age = this._ageValue();
  
          const residentTime = (this.now() - this._responseTime) / 1000;
          return age + residentTime;
      }
  
      _ageValue() {
          return toNumberOrZero(this._resHeaders.age);
      }
  
      /**
       * Value of applicable max-age (or heuristic equivalent) in seconds. This counts since response's `Date`.
       *
       * For an up-to-date value, see `timeToLive()`.
       *
       * @return Number
       */
      maxAge() {
          if (!this.storable() || this._rescc['no-cache']) {
              return 0;
          }
  
          // Shared responses with cookies are cacheable according to the RFC, but IMHO it'd be unwise to do so by default
          // so this implementation requires explicit opt-in via public header
          if (
              this._isShared &&
              (this._resHeaders['set-cookie'] &&
                  !this._rescc.public &&
                  !this._rescc.immutable)
          ) {
              return 0;
          }
  
          if (this._resHeaders.vary === '*') {
              return 0;
          }
  
          if (this._isShared) {
              if (this._rescc['proxy-revalidate']) {
                  return 0;
              }
              // if a response includes the s-maxage directive, a shared cache recipient MUST ignore the Expires field.
              if (this._rescc['s-maxage']) {
                  return toNumberOrZero(this._rescc['s-maxage']);
              }
          }
  
          // If a response includes a Cache-Control field with the max-age directive, a recipient MUST ignore the Expires field.
          if (this._rescc['max-age']) {
              return toNumberOrZero(this._rescc['max-age']);
          }
  
          const defaultMinTtl = this._rescc.immutable ? this._immutableMinTtl : 0;
  
          const serverDate = this.date();
          if (this._resHeaders.expires) {
              const expires = Date.parse(this._resHeaders.expires);
              // A cache recipient MUST interpret invalid date formats, especially the value "0", as representing a time in the past (i.e., "already expired").
              if (Number.isNaN(expires) || expires < serverDate) {
                  return 0;
              }
              return Math.max(defaultMinTtl, (expires - serverDate) / 1000);
          }
  
          if (this._resHeaders['last-modified']) {
              const lastModified = Date.parse(this._resHeaders['last-modified']);
              if (isFinite(lastModified) && serverDate > lastModified) {
                  return Math.max(
                      defaultMinTtl,
                      ((serverDate - lastModified) / 1000) * this._cacheHeuristic
                  );
              }
          }
  
          return defaultMinTtl;
      }
  
      timeToLive() {
          const age = this.maxAge() - this.age();
          const staleIfErrorAge = age + toNumberOrZero(this._rescc['stale-if-error']);
          const staleWhileRevalidateAge = age + toNumberOrZero(this._rescc['stale-while-revalidate']);
          return Math.max(0, age, staleIfErrorAge, staleWhileRevalidateAge) * 1000;
      }
  
      stale() {
          return this.maxAge() <= this.age();
      }
  
      _useStaleIfError() {
          return this.maxAge() + toNumberOrZero(this._rescc['stale-if-error']) > this.age();
      }
  
      useStaleWhileRevalidate() {
          return this.maxAge() + toNumberOrZero(this._rescc['stale-while-revalidate']) > this.age();
      }
  
      static fromObject(obj) {
          return new this(undefined, undefined, { _fromObject: obj });
      }
  
      _fromObject(obj) {
          if (this._responseTime) throw Error('Reinitialized');
          if (!obj || obj.v !== 1) throw Error('Invalid serialization');
  
          this._responseTime = obj.t;
          this._isShared = obj.sh;
          this._cacheHeuristic = obj.ch;
          this._immutableMinTtl =
              obj.imm !== undefined ? obj.imm : 24 * 3600 * 1000;
          this._status = obj.st;
          this._resHeaders = obj.resh;
          this._rescc = obj.rescc;
          this._method = obj.m;
          this._url = obj.u;
          this._host = obj.h;
          this._noAuthorization = obj.a;
          this._reqHeaders = obj.reqh;
          this._reqcc = obj.reqcc;
      }
  
      toObject() {
          return {
              v: 1,
              t: this._responseTime,
              sh: this._isShared,
              ch: this._cacheHeuristic,
              imm: this._immutableMinTtl,
              st: this._status,
              resh: this._resHeaders,
              rescc: this._rescc,
              m: this._method,
              u: this._url,
              h: this._host,
              a: this._noAuthorization,
              reqh: this._reqHeaders,
              reqcc: this._reqcc,
          };
      }
  
      /**
       * Headers for sending to the origin server to revalidate stale response.
       * Allows server to return 304 to allow reuse of the previous response.
       *
       * Hop by hop headers are always stripped.
       * Revalidation headers may be added or removed, depending on request.
       */
      revalidationHeaders(incomingReq) {
          this._assertRequestHasHeaders(incomingReq);
          const headers = this._copyWithoutHopByHopHeaders(incomingReq.headers);
  
          // This implementation does not understand range requests
          delete headers['if-range'];
  
          if (!this._requestMatches(incomingReq, true) || !this.storable()) {
              // revalidation allowed via HEAD
              // not for the same resource, or wasn't allowed to be cached anyway
              delete headers['if-none-match'];
              delete headers['if-modified-since'];
              return headers;
          }
  
          /* MUST send that entity-tag in any cache validation request (using If-Match or If-None-Match) if an entity-tag has been provided by the origin server. */
          if (this._resHeaders.etag) {
              headers['if-none-match'] = headers['if-none-match']
                  ? `${headers['if-none-match']}, ${this._resHeaders.etag}`
                  : this._resHeaders.etag;
          }
  
          // Clients MAY issue simple (non-subrange) GET requests with either weak validators or strong validators. Clients MUST NOT use weak validators in other forms of request.
          const forbidsWeakValidators =
              headers['accept-ranges'] ||
              headers['if-match'] ||
              headers['if-unmodified-since'] ||
              (this._method && this._method != 'GET');
  
          /* SHOULD send the Last-Modified value in non-subrange cache validation requests (using If-Modified-Since) if only a Last-Modified value has been provided by the origin server.
          Note: This implementation does not understand partial responses (206) */
          if (forbidsWeakValidators) {
              delete headers['if-modified-since'];
  
              if (headers['if-none-match']) {
                  const etags = headers['if-none-match']
                      .split(/,/)
                      .filter(etag => {
                          return !/^\s*W\//.test(etag);
                      });
                  if (!etags.length) {
                      delete headers['if-none-match'];
                  } else {
                      headers['if-none-match'] = etags.join(',').trim();
                  }
              }
          } else if (
              this._resHeaders['last-modified'] &&
              !headers['if-modified-since']
          ) {
              headers['if-modified-since'] = this._resHeaders['last-modified'];
          }
  
          return headers;
      }
  
      /**
       * Creates new CachePolicy with information combined from the previews response,
       * and the new revalidation response.
       *
       * Returns {policy, modified} where modified is a boolean indicating
       * whether the response body has been modified, and old cached body can't be used.
       *
       * @return {Object} {policy: CachePolicy, modified: Boolean}
       */
      revalidatedPolicy(request, response) {
          this._assertRequestHasHeaders(request);
          if(this._useStaleIfError() && isErrorResponse(response)) {  // I consider the revalidation request unsuccessful
            return {
              modified: false,
              matches: false,
              policy: this,
            };
          }
          if (!response || !response.headers) {
              throw Error('Response headers missing');
          }
  
          // These aren't going to be supported exactly, since one CachePolicy object
          // doesn't know about all the other cached objects.
          let matches = false;
          if (response.status !== undefined && response.status != 304) {
              matches = false;
          } else if (
              response.headers.etag &&
              !/^\s*W\//.test(response.headers.etag)
          ) {
              // "All of the stored responses with the same strong validator are selected.
              // If none of the stored responses contain the same strong validator,
              // then the cache MUST NOT use the new response to update any stored responses."
              matches =
                  this._resHeaders.etag &&
                  this._resHeaders.etag.replace(/^\s*W\//, '') ===
                      response.headers.etag;
          } else if (this._resHeaders.etag && response.headers.etag) {
              // "If the new response contains a weak validator and that validator corresponds
              // to one of the cache's stored responses,
              // then the most recent of those matching stored responses is selected for update."
              matches =
                  this._resHeaders.etag.replace(/^\s*W\//, '') ===
                  response.headers.etag.replace(/^\s*W\//, '');
          } else if (this._resHeaders['last-modified']) {
              matches =
                  this._resHeaders['last-modified'] ===
                  response.headers['last-modified'];
          } else {
              // If the new response does not include any form of validator (such as in the case where
              // a client generates an If-Modified-Since request from a source other than the Last-Modified
              // response header field), and there is only one stored response, and that stored response also
              // lacks a validator, then that stored response is selected for update.
              if (
                  !this._resHeaders.etag &&
                  !this._resHeaders['last-modified'] &&
                  !response.headers.etag &&
                  !response.headers['last-modified']
              ) {
                  matches = true;
              }
          }
  
          if (!matches) {
              return {
                  policy: new this.constructor(request, response),
                  // Client receiving 304 without body, even if it's invalid/mismatched has no option
                  // but to reuse a cached body. We don't have a good way to tell clients to do
                  // error recovery in such case.
                  modified: response.status != 304,
                  matches: false,
              };
          }
  
          // use other header fields provided in the 304 (Not Modified) response to replace all instances
          // of the corresponding header fields in the stored response.
          const headers = {};
          for (const k in this._resHeaders) {
              headers[k] =
                  k in response.headers && !excludedFromRevalidationUpdate[k]
                      ? response.headers[k]
                      : this._resHeaders[k];
          }
  
          const newResponse = Object.assign({}, response, {
              status: this._status,
              method: this._method,
              headers,
          });
          return {
              policy: new this.constructor(request, newResponse, {
                  shared: this._isShared,
                  cacheHeuristic: this._cacheHeuristic,
                  immutableMinTimeToLive: this._immutableMinTtl,
              }),
              modified: false,
              matches: true,
          };
      }
  };
  
  var lowercaseKeys = object => {
  	const result = {};
  
  	for (const [key, value] of Object.entries(object)) {
  		result[key.toLowerCase()] = value;
  	}
  
  	return result;
  };
  
  const Readable = Stream.Readable;
  
  
  class Response extends Readable {
  	constructor(statusCode, headers, body, url) {
  		if (typeof statusCode !== 'number') {
  			throw new TypeError('Argument `statusCode` should be a number');
  		}
  		if (typeof headers !== 'object') {
  			throw new TypeError('Argument `headers` should be an object');
  		}
  		if (!(body instanceof Buffer)) {
  			throw new TypeError('Argument `body` should be a buffer');
  		}
  		if (typeof url !== 'string') {
  			throw new TypeError('Argument `url` should be a string');
  		}
  
  		super();
  		this.statusCode = statusCode;
  		this.headers = lowercaseKeys(headers);
  		this.body = body;
  		this.url = url;
  	}
  
  	_read() {
  		this.push(this.body);
  		this.push(null);
  	}
  }
  
  var src = Response;
  
  // We define these manually to ensure they're always copied
  // even if they would move up the prototype chain
  // https://nodejs.org/api/http.html#http_class_http_incomingmessage
  const knownProps = [
  	'destroy',
  	'setTimeout',
  	'socket',
  	'headers',
  	'trailers',
  	'rawHeaders',
  	'statusCode',
  	'httpVersion',
  	'httpVersionMinor',
  	'httpVersionMajor',
  	'rawTrailers',
  	'statusMessage'
  ];
  
  var mimicResponse = (fromStream, toStream) => {
  	const fromProps = new Set(Object.keys(fromStream).concat(knownProps));
  
  	for (const prop of fromProps) {
  		// Don't overwrite existing properties
  		if (prop in toStream) {
  			continue;
  		}
  
  		toStream[prop] = typeof fromStream[prop] === 'function' ? fromStream[prop].bind(fromStream) : fromStream[prop];
  	}
  };
  
  const PassThrough = Stream.PassThrough;
  
  
  const cloneResponse = response => {
  	if (!(response && response.pipe)) {
  		throw new TypeError('Parameter `response` must be a response stream.');
  	}
  
  	const clone = new PassThrough();
  	mimicResponse(response, clone);
  
  	return response.pipe(clone);
  };
  
  var src$1 = cloneResponse;
  
  //TODO: handle reviver/dehydrate function like normal
  //and handle indentation, like normal.
  //if anyone needs this... please send pull request.
  
  var stringify = function stringify (o) {
    if('undefined' == typeof o) return o
  
    if(o && Buffer.isBuffer(o))
      return JSON.stringify(':base64:' + o.toString('base64'))
  
    if(o && o.toJSON)
      o =  o.toJSON();
  
    if(o && 'object' === typeof o) {
      var s = '';
      var array = Array.isArray(o);
      s = array ? '[' : '{';
      var first = true;
  
      for(var k in o) {
        var ignore = 'function' == typeof o[k] || (!array && 'undefined' === typeof o[k]);
        if(Object.hasOwnProperty.call(o, k) && !ignore) {
          if(!first)
            s += ',';
          first = false;
          if (array) {
            if(o[k] == undefined)
              s += 'null';
            else
              s += stringify(o[k]);
          } else if (o[k] !== void(0)) {
            s += stringify(k) + ':' + stringify(o[k]);
          }
        }
      }
  
      s += array ? ']' : '}';
  
      return s
    } else if ('string' === typeof o) {
      return JSON.stringify(/^:/.test(o) ? ':' + o : o)
    } else if ('undefined' === typeof o) {
      return 'null';
    } else
      return JSON.stringify(o)
  };
  
  var parse = function (s) {
    return JSON.parse(s, function (key, value) {
      if('string' === typeof value) {
        if(/^:base64:/.test(value))
          return Buffer.from(value.substring(8), 'base64')
        else
          return /^:/.test(value) ? value.substring(1) : value 
      }
      return value
    })
  };
  
  var jsonBuffer = {
  	stringify: stringify,
  	parse: parse
  };
  
  const loadStore = opts => {
  	if (opts.adapter || opts.uri) {
  		const adapter = opts.adapter || /^[^:]*/.exec(opts.uri)[0];
  		return new (commonjsRequire())(opts);
  	}
  
  	return new Map();
  };
  
  class Keyv extends events {
  	constructor(uri, opts) {
  		super();
  		this.opts = Object.assign(
  			{
  				namespace: 'keyv',
  				serialize: jsonBuffer.stringify,
  				deserialize: jsonBuffer.parse
  			},
  			(typeof uri === 'string') ? { uri } : uri,
  			opts
  		);
  
  		if (!this.opts.store) {
  			const adapterOpts = Object.assign({}, this.opts);
  			this.opts.store = loadStore(adapterOpts);
  		}
  
  		if (typeof this.opts.store.on === 'function') {
  			this.opts.store.on('error', err => this.emit('error', err));
  		}
  
  		this.opts.store.namespace = this.opts.namespace;
  	}
  
  	_getKeyPrefix(key) {
  		return `${this.opts.namespace}:${key}`;
  	}
  
  	get(key, opts) {
  		const keyPrefixed = this._getKeyPrefix(key);
  		const { store } = this.opts;
  		return Promise.resolve()
  			.then(() => store.get(keyPrefixed))
  			.then(data => {
  				return (typeof data === 'string') ? this.opts.deserialize(data) : data;
  			})
  			.then(data => {
  				if (data === undefined) {
  					return undefined;
  				}
  
  				if (typeof data.expires === 'number' && Date.now() > data.expires) {
  					this.delete(key);
  					return undefined;
  				}
  
  				return (opts && opts.raw) ? data : data.value;
  			});
  	}
  
  	set(key, value, ttl) {
  		const keyPrefixed = this._getKeyPrefix(key);
  		if (typeof ttl === 'undefined') {
  			ttl = this.opts.ttl;
  		}
  
  		if (ttl === 0) {
  			ttl = undefined;
  		}
  
  		const { store } = this.opts;
  
  		return Promise.resolve()
  			.then(() => {
  				const expires = (typeof ttl === 'number') ? (Date.now() + ttl) : null;
  				value = { value, expires };
  				return this.opts.serialize(value);
  			})
  			.then(value => store.set(keyPrefixed, value, ttl))
  			.then(() => true);
  	}
  
  	delete(key) {
  		const keyPrefixed = this._getKeyPrefix(key);
  		const { store } = this.opts;
  		return Promise.resolve()
  			.then(() => store.delete(keyPrefixed));
  	}
  
  	clear() {
  		const { store } = this.opts;
  		return Promise.resolve()
  			.then(() => store.clear());
  	}
  }
  
  var src$2 = Keyv;
  
  class CacheableRequest {
  	constructor(request, cacheAdapter) {
  		if (typeof request !== 'function') {
  			throw new TypeError('Parameter `request` must be a function');
  		}
  
  		this.cache = new src$2({
  			uri: typeof cacheAdapter === 'string' && cacheAdapter,
  			store: typeof cacheAdapter !== 'string' && cacheAdapter,
  			namespace: 'cacheable-request'
  		});
  
  		return this.createCacheableRequest(request);
  	}
  
  	createCacheableRequest(request) {
  		return (opts, cb) => {
  			let url;
  			if (typeof opts === 'string') {
  				url = normalizeUrlObject(Url.parse(opts));
  				opts = {};
  			} else if (opts instanceof Url.URL) {
  				url = normalizeUrlObject(Url.parse(opts.toString()));
  				opts = {};
  			} else {
  				const [pathname, ...searchParts] = (opts.path || '').split('?');
  				const search = searchParts.length > 0 ?
  					`?${searchParts.join('?')}` :
  					'';
  				url = normalizeUrlObject({ ...opts, pathname, search });
  			}
  
  			opts = {
  				headers: {},
  				method: 'GET',
  				cache: true,
  				strictTtl: false,
  				automaticFailover: false,
  				...opts,
  				...urlObjectToRequestOptions(url)
  			};
  			opts.headers = lowercaseKeys(opts.headers);
  
  			const ee = new events();
  			const normalizedUrlString = normalizeUrl_1(
  				Url.format(url),
  				{
  					stripWWW: false,
  					removeTrailingSlash: false,
  					stripAuthentication: false
  				}
  			);
  			const key = `${opts.method}:${normalizedUrlString}`;
  			let revalidate = false;
  			let madeRequest = false;
  
  			const makeRequest = opts => {
  				madeRequest = true;
  				let requestErrored = false;
  				let requestErrorCallback;
  
  				const requestErrorPromise = new Promise(resolve => {
  					requestErrorCallback = () => {
  						if (!requestErrored) {
  							requestErrored = true;
  							resolve();
  						}
  					};
  				});
  
  				const handler = response => {
  					if (revalidate && !opts.forceRefresh) {
  						response.status = response.statusCode;
  						const revalidatedPolicy = httpCacheSemantics.fromObject(revalidate.cachePolicy).revalidatedPolicy(opts, response);
  						if (!revalidatedPolicy.modified) {
  							const headers = revalidatedPolicy.policy.responseHeaders();
  							response = new src(revalidate.statusCode, headers, revalidate.body, revalidate.url);
  							response.cachePolicy = revalidatedPolicy.policy;
  							response.fromCache = true;
  						}
  					}
  
  					if (!response.fromCache) {
  						response.cachePolicy = new httpCacheSemantics(opts, response, opts);
  						response.fromCache = false;
  					}
  
  					let clonedResponse;
  					if (opts.cache && response.cachePolicy.storable()) {
  						clonedResponse = src$1(response);
  
  						(async () => {
  							try {
  								const bodyPromise = getStream_1.buffer(response);
  
  								await Promise.race([
  									requestErrorPromise,
  									new Promise(resolve => response.once('end', resolve))
  								]);
  
  								if (requestErrored) {
  									return;
  								}
  
  								const body = await bodyPromise;
  
  								const value = {
  									cachePolicy: response.cachePolicy.toObject(),
  									url: response.url,
  									statusCode: response.fromCache ? revalidate.statusCode : response.statusCode,
  									body
  								};
  
  								let ttl = opts.strictTtl ? response.cachePolicy.timeToLive() : undefined;
  								if (opts.maxTtl) {
  									ttl = ttl ? Math.min(ttl, opts.maxTtl) : opts.maxTtl;
  								}
  
  								await this.cache.set(key, value, ttl);
  							} catch (error) {
  								ee.emit('error', new CacheableRequest.CacheError(error));
  							}
  						})();
  					} else if (opts.cache && revalidate) {
  						(async () => {
  							try {
  								await this.cache.delete(key);
  							} catch (error) {
  								ee.emit('error', new CacheableRequest.CacheError(error));
  							}
  						})();
  					}
  
  					ee.emit('response', clonedResponse || response);
  					if (typeof cb === 'function') {
  						cb(clonedResponse || response);
  					}
  				};
  
  				try {
  					const req = request(opts, handler);
  					req.once('error', requestErrorCallback);
  					req.once('abort', requestErrorCallback);
  					ee.emit('request', req);
  				} catch (error) {
  					ee.emit('error', new CacheableRequest.RequestError(error));
  				}
  			};
  
  			(async () => {
  				const get = async opts => {
  					await Promise.resolve();
  
  					const cacheEntry = opts.cache ? await this.cache.get(key) : undefined;
  					if (typeof cacheEntry === 'undefined') {
  						return makeRequest(opts);
  					}
  
  					const policy = httpCacheSemantics.fromObject(cacheEntry.cachePolicy);
  					if (policy.satisfiesWithoutRevalidation(opts) && !opts.forceRefresh) {
  						const headers = policy.responseHeaders();
  						const response = new src(cacheEntry.statusCode, headers, cacheEntry.body, cacheEntry.url);
  						response.cachePolicy = policy;
  						response.fromCache = true;
  
  						ee.emit('response', response);
  						if (typeof cb === 'function') {
  							cb(response);
  						}
  					} else {
  						revalidate = cacheEntry;
  						opts.headers = policy.revalidationHeaders(opts);
  						makeRequest(opts);
  					}
  				};
  
  				const errorHandler = error => ee.emit('error', new CacheableRequest.CacheError(error));
  				this.cache.once('error', errorHandler);
  				ee.on('response', () => this.cache.removeListener('error', errorHandler));
  
  				try {
  					await get(opts);
  				} catch (error) {
  					if (opts.automaticFailover && !madeRequest) {
  						makeRequest(opts);
  					}
  
  					ee.emit('error', new CacheableRequest.CacheError(error));
  				}
  			})();
  
  			return ee;
  		};
  	}
  }
  
  function urlObjectToRequestOptions(url) {
  	const options = { ...url };
  	options.path = `${url.pathname || '/'}${url.search || ''}`;
  	delete options.pathname;
  	delete options.search;
  	return options;
  }
  
  function normalizeUrlObject(url) {
  	// If url was parsed by url.parse or new URL:
  	// - hostname will be set
  	// - host will be hostname[:port]
  	// - port will be set if it was explicit in the parsed string
  	// Otherwise, url was from request options:
  	// - hostname or host may be set
  	// - host shall not have port encoded
  	return {
  		protocol: url.protocol,
  		auth: url.auth,
  		hostname: url.hostname || url.host || 'localhost',
  		port: url.port,
  		pathname: url.pathname,
  		search: url.search
  	};
  }
  
  CacheableRequest.RequestError = class extends Error {
  	constructor(error) {
  		super(error.message);
  		this.name = 'RequestError';
  		Object.assign(this, error);
  	}
  };
  
  CacheableRequest.CacheError = class extends Error {
  	constructor(error) {
  		super(error.message);
  		this.name = 'CacheError';
  		Object.assign(this, error);
  	}
  };
  
  var src$3 = CacheableRequest;
  
  // We define these manually to ensure they're always copied
  // even if they would move up the prototype chain
  // https://nodejs.org/api/http.html#http_class_http_incomingmessage
  const knownProperties = [
  	'aborted',
  	'complete',
  	'headers',
  	'httpVersion',
  	'httpVersionMinor',
  	'httpVersionMajor',
  	'method',
  	'rawHeaders',
  	'rawTrailers',
  	'setTimeout',
  	'socket',
  	'statusCode',
  	'statusMessage',
  	'trailers',
  	'url'
  ];
  
  var mimicResponse$1 = (fromStream, toStream) => {
  	if (toStream._readableState.autoDestroy) {
  		throw new Error('The second stream must have the `autoDestroy` option set to `false`');
  	}
  
  	const fromProperties = new Set(Object.keys(fromStream).concat(knownProperties));
  
  	const properties = {};
  
  	for (const property of fromProperties) {
  		// Don't overwrite existing properties.
  		if (property in toStream) {
  			continue;
  		}
  
  		properties[property] = {
  			get() {
  				const value = fromStream[property];
  				const isFunction = typeof value === 'function';
  
  				return isFunction ? value.bind(fromStream) : value;
  			},
  			set(value) {
  				fromStream[property] = value;
  			},
  			enumerable: true,
  			configurable: false
  		};
  	}
  
  	Object.defineProperties(toStream, properties);
  
  	fromStream.once('aborted', () => {
  		toStream.destroy();
  
  		toStream.emit('aborted');
  	});
  
  	fromStream.once('close', () => {
  		if (fromStream.complete) {
  			if (toStream.readable) {
  				toStream.once('end', () => {
  					toStream.emit('close');
  				});
  			} else {
  				toStream.emit('close');
  			}
  		} else {
  			toStream.emit('close');
  		}
  	});
  
  	return toStream;
  };
  
  const {Transform, PassThrough: PassThrough$1} = Stream;
  
  
  
  var decompressResponse = response => {
  	const contentEncoding = (response.headers['content-encoding'] || '').toLowerCase();
  
  	if (!['gzip', 'deflate', 'br'].includes(contentEncoding)) {
  		return response;
  	}
  
  	// TODO: Remove this when targeting Node.js 12.
  	const isBrotli = contentEncoding === 'br';
  	if (isBrotli && typeof zlib.createBrotliDecompress !== 'function') {
  		response.destroy(new Error('Brotli is not supported on Node.js < 12'));
  		return response;
  	}
  
  	let isEmpty = true;
  
  	const checker = new Transform({
  		transform(data, _encoding, callback) {
  			isEmpty = false;
  
  			callback(null, data);
  		},
  
  		flush(callback) {
  			callback();
  		}
  	});
  
  	const finalStream = new PassThrough$1({
  		autoDestroy: false,
  		destroy(error, callback) {
  			response.destroy();
  
  			callback(error);
  		}
  	});
  
  	const decompressStream = isBrotli ? zlib.createBrotliDecompress() : zlib.createUnzip();
  
  	decompressStream.once('error', error => {
  		if (isEmpty && !response.readable) {
  			finalStream.end();
  			return;
  		}
  
  		finalStream.destroy(error);
  	});
  
  	mimicResponse$1(response, finalStream);
  	response.pipe(checker).pipe(decompressStream).pipe(finalStream);
  
  	return finalStream;
  };
  
  class QuickLRU {
  	constructor(options = {}) {
  		if (!(options.maxSize && options.maxSize > 0)) {
  			throw new TypeError('`maxSize` must be a number greater than 0');
  		}
  
  		this.maxSize = options.maxSize;
  		this.onEviction = options.onEviction;
  		this.cache = new Map();
  		this.oldCache = new Map();
  		this._size = 0;
  	}
  
  	_set(key, value) {
  		this.cache.set(key, value);
  		this._size++;
  
  		if (this._size >= this.maxSize) {
  			this._size = 0;
  
  			if (typeof this.onEviction === 'function') {
  				for (const [key, value] of this.oldCache.entries()) {
  					this.onEviction(key, value);
  				}
  			}
  
  			this.oldCache = this.cache;
  			this.cache = new Map();
  		}
  	}
  
  	get(key) {
  		if (this.cache.has(key)) {
  			return this.cache.get(key);
  		}
  
  		if (this.oldCache.has(key)) {
  			const value = this.oldCache.get(key);
  			this.oldCache.delete(key);
  			this._set(key, value);
  			return value;
  		}
  	}
  
  	set(key, value) {
  		if (this.cache.has(key)) {
  			this.cache.set(key, value);
  		} else {
  			this._set(key, value);
  		}
  
  		return this;
  	}
  
  	has(key) {
  		return this.cache.has(key) || this.oldCache.has(key);
  	}
  
  	peek(key) {
  		if (this.cache.has(key)) {
  			return this.cache.get(key);
  		}
  
  		if (this.oldCache.has(key)) {
  			return this.oldCache.get(key);
  		}
  	}
  
  	delete(key) {
  		const deleted = this.cache.delete(key);
  		if (deleted) {
  			this._size--;
  		}
  
  		return this.oldCache.delete(key) || deleted;
  	}
  
  	clear() {
  		this.cache.clear();
  		this.oldCache.clear();
  		this._size = 0;
  	}
  
  	* keys() {
  		for (const [key] of this) {
  			yield key;
  		}
  	}
  
  	* values() {
  		for (const [, value] of this) {
  			yield value;
  		}
  	}
  
  	* [Symbol.iterator]() {
  		for (const item of this.cache) {
  			yield item;
  		}
  
  		for (const item of this.oldCache) {
  			const [key] = item;
  			if (!this.cache.has(key)) {
  				yield item;
  			}
  		}
  	}
  
  	get size() {
  		let oldCacheSize = 0;
  		for (const key of this.oldCache.keys()) {
  			if (!this.cache.has(key)) {
  				oldCacheSize++;
  			}
  		}
  
  		return Math.min(this._size + oldCacheSize, this.maxSize);
  	}
  }
  
  var quickLru = QuickLRU;
  
  const kCurrentStreamsCount = Symbol('currentStreamsCount');
  const kRequest = Symbol('request');
  const kOriginSet = Symbol('cachedOriginSet');
  const kGracefullyClosing = Symbol('gracefullyClosing');
  
  const nameKeys = [
  	// `http2.connect()` options
  	'maxDeflateDynamicTableSize',
  	'maxSessionMemory',
  	'maxHeaderListPairs',
  	'maxOutstandingPings',
  	'maxReservedRemoteStreams',
  	'maxSendHeaderBlockLength',
  	'paddingStrategy',
  
  	// `tls.connect()` options
  	'localAddress',
  	'path',
  	'rejectUnauthorized',
  	'minDHSize',
  
  	// `tls.createSecureContext()` options
  	'ca',
  	'cert',
  	'clientCertEngine',
  	'ciphers',
  	'key',
  	'pfx',
  	'servername',
  	'minVersion',
  	'maxVersion',
  	'secureProtocol',
  	'crl',
  	'honorCipherOrder',
  	'ecdhCurve',
  	'dhparam',
  	'secureOptions',
  	'sessionIdContext'
  ];
  
  const getSortedIndex = (array, value, compare) => {
  	let low = 0;
  	let high = array.length;
  
  	while (low < high) {
  		const mid = (low + high) >>> 1;
  
  		/* istanbul ignore next */
  		if (compare(array[mid], value)) {
  			// This never gets called because we use descending sort. Better to have this anyway.
  			low = mid + 1;
  		} else {
  			high = mid;
  		}
  	}
  
  	return low;
  };
  
  const compareSessions = (a, b) => {
  	return a.remoteSettings.maxConcurrentStreams > b.remoteSettings.maxConcurrentStreams;
  };
  
  // See https://tools.ietf.org/html/rfc8336
  const closeCoveredSessions = (where, session) => {
  	// Clients SHOULD NOT emit new requests on any connection whose Origin
  	// Set is a proper subset of another connection's Origin Set, and they
  	// SHOULD close it once all outstanding requests are satisfied.
  	for (const coveredSession of where) {
  		if (
  			// The set is a proper subset when its length is less than the other set.
  			coveredSession[kOriginSet].length < session[kOriginSet].length &&
  
  			// And the other set includes all elements of the subset.
  			coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) &&
  
  			// Makes sure that the session can handle all requests from the covered session.
  			coveredSession[kCurrentStreamsCount] + session[kCurrentStreamsCount] <= session.remoteSettings.maxConcurrentStreams
  		) {
  			// This allows pending requests to finish and prevents making new requests.
  			gracefullyClose(coveredSession);
  		}
  	}
  };
  
  // This is basically inverted `closeCoveredSessions(...)`.
  const closeSessionIfCovered = (where, coveredSession) => {
  	for (const session of where) {
  		if (
  			coveredSession[kOriginSet].length < session[kOriginSet].length &&
  			coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) &&
  			coveredSession[kCurrentStreamsCount] + session[kCurrentStreamsCount] <= session.remoteSettings.maxConcurrentStreams
  		) {
  			gracefullyClose(coveredSession);
  		}
  	}
  };
  
  const getSessions = ({agent, isFree}) => {
  	const result = {};
  
  	// eslint-disable-next-line guard-for-in
  	for (const normalizedOptions in agent.sessions) {
  		const sessions = agent.sessions[normalizedOptions];
  
  		const filtered = sessions.filter(session => {
  			const result = session[Agent.kCurrentStreamsCount] < session.remoteSettings.maxConcurrentStreams;
  
  			return isFree ? result : !result;
  		});
  
  		if (filtered.length !== 0) {
  			result[normalizedOptions] = filtered;
  		}
  	}
  
  	return result;
  };
  
  const gracefullyClose = session => {
  	session[kGracefullyClosing] = true;
  
  	if (session[kCurrentStreamsCount] === 0) {
  		session.close();
  	}
  };
  
  class Agent extends events {
  	constructor({timeout = 60000, maxSessions = Infinity, maxFreeSessions = 10, maxCachedTlsSessions = 100} = {}) {
  		super();
  
  		// A session is considered busy when its current streams count
  		// is equal to or greater than the `maxConcurrentStreams` value.
  
  		// A session is considered free when its current streams count
  		// is less than the `maxConcurrentStreams` value.
  
  		// SESSIONS[NORMALIZED_OPTIONS] = [];
  		this.sessions = {};
  
  		// The queue for creating new sessions. It looks like this:
  		// QUEUE[NORMALIZED_OPTIONS][NORMALIZED_ORIGIN] = ENTRY_FUNCTION
  		//
  		// The entry function has `listeners`, `completed` and `destroyed` properties.
  		// `listeners` is an array of objects containing `resolve` and `reject` functions.
  		// `completed` is a boolean. It's set to true after ENTRY_FUNCTION is executed.
  		// `destroyed` is a boolean. If it's set to true, the session will be destroyed if hasn't connected yet.
  		this.queue = {};
  
  		// Each session will use this timeout value.
  		this.timeout = timeout;
  
  		// Max sessions in total
  		this.maxSessions = maxSessions;
  
  		// Max free sessions in total
  		// TODO: decreasing `maxFreeSessions` should close some sessions
  		this.maxFreeSessions = maxFreeSessions;
  
  		this._freeSessionsCount = 0;
  		this._sessionsCount = 0;
  
  		// We don't support push streams by default.
  		this.settings = {
  			enablePush: false
  		};
  
  		// Reusing TLS sessions increases performance.
  		this.tlsSessionCache = new quickLru({maxSize: maxCachedTlsSessions});
  	}
  
  	static normalizeOrigin(url, servername) {
  		if (typeof url === 'string') {
  			url = new URL(url);
  		}
  
  		if (servername && url.hostname !== servername) {
  			url.hostname = servername;
  		}
  
  		return url.origin;
  	}
  
  	normalizeOptions(options) {
  		let normalized = '';
  
  		if (options) {
  			for (const key of nameKeys) {
  				if (options[key]) {
  					normalized += `:${options[key]}`;
  				}
  			}
  		}
  
  		return normalized;
  	}
  
  	_tryToCreateNewSession(normalizedOptions, normalizedOrigin) {
  		if (!(normalizedOptions in this.queue) || !(normalizedOrigin in this.queue[normalizedOptions])) {
  			return;
  		}
  
  		const item = this.queue[normalizedOptions][normalizedOrigin];
  
  		// The entry function can be run only once.
  		// BUG: The session may be never created when:
  		// - the first condition is false AND
  		// - this function is never called with the same arguments in the future.
  		if (this._sessionsCount < this.maxSessions && !item.completed) {
  			item.completed = true;
  
  			item();
  		}
  	}
  
  	getSession(origin, options, listeners) {
  		return new Promise((resolve, reject) => {
  			if (Array.isArray(listeners)) {
  				listeners = [...listeners];
  
  				// Resolve the current promise ASAP, we're just moving the listeners.
  				// They will be executed at a different time.
  				resolve();
  			} else {
  				listeners = [{resolve, reject}];
  			}
  
  			const normalizedOptions = this.normalizeOptions(options);
  			const normalizedOrigin = Agent.normalizeOrigin(origin, options && options.servername);
  
  			if (normalizedOrigin === undefined) {
  				for (const {reject} of listeners) {
  					reject(new TypeError('The `origin` argument needs to be a string or an URL object'));
  				}
  
  				return;
  			}
  
  			if (normalizedOptions in this.sessions) {
  				const sessions = this.sessions[normalizedOptions];
  
  				let maxConcurrentStreams = -1;
  				let currentStreamsCount = -1;
  				let optimalSession;
  
  				// We could just do this.sessions[normalizedOptions].find(...) but that isn't optimal.
  				// Additionally, we are looking for session which has biggest current pending streams count.
  				for (const session of sessions) {
  					const sessionMaxConcurrentStreams = session.remoteSettings.maxConcurrentStreams;
  
  					if (sessionMaxConcurrentStreams < maxConcurrentStreams) {
  						break;
  					}
  
  					if (session[kOriginSet].includes(normalizedOrigin)) {
  						const sessionCurrentStreamsCount = session[kCurrentStreamsCount];
  
  						if (
  							sessionCurrentStreamsCount >= sessionMaxConcurrentStreams ||
  							session[kGracefullyClosing] ||
  							// Unfortunately the `close` event isn't called immediately,
  							// so `session.destroyed` is `true`, but `session.closed` is `false`.
  							session.destroyed
  						) {
  							continue;
  						}
  
  						// We only need set this once.
  						if (!optimalSession) {
  							maxConcurrentStreams = sessionMaxConcurrentStreams;
  						}
  
  						// We're looking for the session which has biggest current pending stream count,
  						// in order to minimalize the amount of active sessions.
  						if (sessionCurrentStreamsCount > currentStreamsCount) {
  							optimalSession = session;
  							currentStreamsCount = sessionCurrentStreamsCount;
  						}
  					}
  				}
  
  				if (optimalSession) {
  					/* istanbul ignore next: safety check */
  					if (listeners.length !== 1) {
  						for (const {reject} of listeners) {
  							const error = new Error(
  								`Expected the length of listeners to be 1, got ${listeners.length}.\n` +
  								'Please report this to https://github.com/szmarczak/http2-wrapper/'
  							);
  
  							reject(error);
  						}
  
  						return;
  					}
  
  					listeners[0].resolve(optimalSession);
  					return;
  				}
  			}
  
  			if (normalizedOptions in this.queue) {
  				if (normalizedOrigin in this.queue[normalizedOptions]) {
  					// There's already an item in the queue, just attach ourselves to it.
  					this.queue[normalizedOptions][normalizedOrigin].listeners.push(...listeners);
  
  					// This shouldn't be executed here.
  					// See the comment inside _tryToCreateNewSession.
  					this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
  					return;
  				}
  			} else {
  				this.queue[normalizedOptions] = {};
  			}
  
  			// The entry must be removed from the queue IMMEDIATELY when:
  			// 1. the session connects successfully,
  			// 2. an error occurs.
  			const removeFromQueue = () => {
  				// Our entry can be replaced. We cannot remove the new one.
  				if (normalizedOptions in this.queue && this.queue[normalizedOptions][normalizedOrigin] === entry) {
  					delete this.queue[normalizedOptions][normalizedOrigin];
  
  					if (Object.keys(this.queue[normalizedOptions]).length === 0) {
  						delete this.queue[normalizedOptions];
  					}
  				}
  			};
  
  			// The main logic is here
  			const entry = () => {
  				const name = `${normalizedOrigin}:${normalizedOptions}`;
  				let receivedSettings = false;
  
  				try {
  					const session = http2.connect(origin, {
  						createConnection: this.createConnection,
  						settings: this.settings,
  						session: this.tlsSessionCache.get(name),
  						...options
  					});
  					session[kCurrentStreamsCount] = 0;
  					session[kGracefullyClosing] = false;
  
  					const isFree = () => session[kCurrentStreamsCount] < session.remoteSettings.maxConcurrentStreams;
  					let wasFree = true;
  
  					session.socket.once('session', tlsSession => {
  						this.tlsSessionCache.set(name, tlsSession);
  					});
  
  					session.once('error', error => {
  						// Listeners are empty when the session successfully connected.
  						for (const {reject} of listeners) {
  							reject(error);
  						}
  
  						// The connection got broken, purge the cache.
  						this.tlsSessionCache.delete(name);
  					});
  
  					session.setTimeout(this.timeout, () => {
  						// Terminates all streams owned by this session.
  						// TODO: Maybe the streams should have a "Session timed out" error?
  						session.destroy();
  					});
  
  					session.once('close', () => {
  						if (receivedSettings) {
  							// 1. If it wasn't free then no need to decrease because
  							//    it has been decreased already in session.request().
  							// 2. `stream.once('close')` won't increment the count
  							//    because the session is already closed.
  							if (wasFree) {
  								this._freeSessionsCount--;
  							}
  
  							this._sessionsCount--;
  
  							// This cannot be moved to the stream logic,
  							// because there may be a session that hadn't made a single request.
  							const where = this.sessions[normalizedOptions];
  							where.splice(where.indexOf(session), 1);
  
  							if (where.length === 0) {
  								delete this.sessions[normalizedOptions];
  							}
  						} else {
  							// Broken connection
  							const error = new Error('Session closed without receiving a SETTINGS frame');
  							error.code = 'HTTP2WRAPPER_NOSETTINGS';
  
  							for (const {reject} of listeners) {
  								reject(error);
  							}
  
  							removeFromQueue();
  						}
  
  						// There may be another session awaiting.
  						this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
  					});
  
  					// Iterates over the queue and processes listeners.
  					const processListeners = () => {
  						if (!(normalizedOptions in this.queue) || !isFree()) {
  							return;
  						}
  
  						for (const origin of session[kOriginSet]) {
  							if (origin in this.queue[normalizedOptions]) {
  								const {listeners} = this.queue[normalizedOptions][origin];
  
  								// Prevents session overloading.
  								while (listeners.length !== 0 && isFree()) {
  									// We assume `resolve(...)` calls `request(...)` *directly*,
  									// otherwise the session will get overloaded.
  									listeners.shift().resolve(session);
  								}
  
  								const where = this.queue[normalizedOptions];
  								if (where[origin].listeners.length === 0) {
  									delete where[origin];
  
  									if (Object.keys(where).length === 0) {
  										delete this.queue[normalizedOptions];
  										break;
  									}
  								}
  
  								// We're no longer free, no point in continuing.
  								if (!isFree()) {
  									break;
  								}
  							}
  						}
  					};
  
  					// The Origin Set cannot shrink. No need to check if it suddenly became covered by another one.
  					session.on('origin', () => {
  						session[kOriginSet] = session.originSet;
  
  						if (!isFree()) {
  							// The session is full.
  							return;
  						}
  
  						processListeners();
  
  						// Close covered sessions (if possible).
  						closeCoveredSessions(this.sessions[normalizedOptions], session);
  					});
  
  					session.once('remoteSettings', () => {
  						// Fix Node.js bug preventing the process from exiting
  						session.ref();
  						session.unref();
  
  						this._sessionsCount++;
  
  						// The Agent could have been destroyed already.
  						if (entry.destroyed) {
  							const error = new Error('Agent has been destroyed');
  
  							for (const listener of listeners) {
  								listener.reject(error);
  							}
  
  							session.destroy();
  							return;
  						}
  
  						session[kOriginSet] = session.originSet;
  
  						{
  							const where = this.sessions;
  
  							if (normalizedOptions in where) {
  								const sessions = where[normalizedOptions];
  								sessions.splice(getSortedIndex(sessions, session, compareSessions), 0, session);
  							} else {
  								where[normalizedOptions] = [session];
  							}
  						}
  
  						this._freeSessionsCount += 1;
  						receivedSettings = true;
  
  						this.emit('session', session);
  
  						processListeners();
  						removeFromQueue();
  
  						// TODO: Close last recently used (or least used?) session
  						if (session[kCurrentStreamsCount] === 0 && this._freeSessionsCount > this.maxFreeSessions) {
  							session.close();
  						}
  
  						// Check if we haven't managed to execute all listeners.
  						if (listeners.length !== 0) {
  							// Request for a new session with predefined listeners.
  							this.getSession(normalizedOrigin, options, listeners);
  							listeners.length = 0;
  						}
  
  						// `session.remoteSettings.maxConcurrentStreams` might get increased
  						session.on('remoteSettings', () => {
  							processListeners();
  
  							// In case the Origin Set changes
  							closeCoveredSessions(this.sessions[normalizedOptions], session);
  						});
  					});
  
  					// Shim `session.request()` in order to catch all streams
  					session[kRequest] = session.request;
  					session.request = (headers, streamOptions) => {
  						if (session[kGracefullyClosing]) {
  							throw new Error('The session is gracefully closing. No new streams are allowed.');
  						}
  
  						const stream = session[kRequest](headers, streamOptions);
  
  						// The process won't exit until the session is closed or all requests are gone.
  						session.ref();
  
  						++session[kCurrentStreamsCount];
  
  						if (session[kCurrentStreamsCount] === session.remoteSettings.maxConcurrentStreams) {
  							this._freeSessionsCount--;
  						}
  
  						stream.once('close', () => {
  							wasFree = isFree();
  
  							--session[kCurrentStreamsCount];
  
  							if (!session.destroyed && !session.closed) {
  								closeSessionIfCovered(this.sessions[normalizedOptions], session);
  
  								if (isFree() && !session.closed) {
  									if (!wasFree) {
  										this._freeSessionsCount++;
  
  										wasFree = true;
  									}
  
  									const isEmpty = session[kCurrentStreamsCount] === 0;
  
  									if (isEmpty) {
  										session.unref();
  									}
  
  									if (
  										isEmpty &&
  										(
  											this._freeSessionsCount > this.maxFreeSessions ||
  											session[kGracefullyClosing]
  										)
  									) {
  										session.close();
  									} else {
  										closeCoveredSessions(this.sessions[normalizedOptions], session);
  										processListeners();
  									}
  								}
  							}
  						});
  
  						return stream;
  					};
  				} catch (error) {
  					for (const listener of listeners) {
  						listener.reject(error);
  					}
  
  					removeFromQueue();
  				}
  			};
  
  			entry.listeners = listeners;
  			entry.completed = false;
  			entry.destroyed = false;
  
  			this.queue[normalizedOptions][normalizedOrigin] = entry;
  			this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
  		});
  	}
  
  	request(origin, options, headers, streamOptions) {
  		return new Promise((resolve, reject) => {
  			this.getSession(origin, options, [{
  				reject,
  				resolve: session => {
  					try {
  						resolve(session.request(headers, streamOptions));
  					} catch (error) {
  						reject(error);
  					}
  				}
  			}]);
  		});
  	}
  
  	createConnection(origin, options) {
  		return Agent.connect(origin, options);
  	}
  
  	static connect(origin, options) {
  		options.ALPNProtocols = ['h2'];
  
  		const port = origin.port || 443;
  		const host = origin.hostname || origin.host;
  
  		if (typeof options.servername === 'undefined') {
  			options.servername = host;
  		}
  
  		return tls.connect(port, host, options);
  	}
  
  	closeFreeSessions() {
  		for (const sessions of Object.values(this.sessions)) {
  			for (const session of sessions) {
  				if (session[kCurrentStreamsCount] === 0) {
  					session.close();
  				}
  			}
  		}
  	}
  
  	destroy(reason) {
  		for (const sessions of Object.values(this.sessions)) {
  			for (const session of sessions) {
  				session.destroy(reason);
  			}
  		}
  
  		for (const entriesOfAuthority of Object.values(this.queue)) {
  			for (const entry of Object.values(entriesOfAuthority)) {
  				entry.destroyed = true;
  			}
  		}
  
  		// New requests should NOT attach to destroyed sessions
  		this.queue = {};
  	}
  
  	get freeSessions() {
  		return getSessions({agent: this, isFree: true});
  	}
  
  	get busySessions() {
  		return getSessions({agent: this, isFree: false});
  	}
  }
  
  Agent.kCurrentStreamsCount = kCurrentStreamsCount;
  Agent.kGracefullyClosing = kGracefullyClosing;
  
  var agent = {
  	Agent,
  	globalAgent: new Agent()
  };
  
  const {Readable: Readable$1} = Stream;
  
  class IncomingMessage extends Readable$1 {
  	constructor(socket, highWaterMark) {
  		super({
  			highWaterMark,
  			autoDestroy: false
  		});
  
  		this.statusCode = null;
  		this.statusMessage = '';
  		this.httpVersion = '2.0';
  		this.httpVersionMajor = 2;
  		this.httpVersionMinor = 0;
  		this.headers = {};
  		this.trailers = {};
  		this.req = null;
  
  		this.aborted = false;
  		this.complete = false;
  		this.upgrade = null;
  
  		this.rawHeaders = [];
  		this.rawTrailers = [];
  
  		this.socket = socket;
  		this.connection = socket;
  
  		this._dumped = false;
  	}
  
  	_destroy(error) {
  		this.req._request.destroy(error);
  	}
  
  	setTimeout(ms, callback) {
  		this.req.setTimeout(ms, callback);
  		return this;
  	}
  
  	_dump() {
  		if (!this._dumped) {
  			this._dumped = true;
  
  			this.removeAllListeners('data');
  			this.resume();
  		}
  	}
  
  	_read() {
  		if (this.req) {
  			this.req._request.resume();
  		}
  	}
  }
  
  var incomingMessage = IncomingMessage;
  
  /* istanbul ignore file: https://github.com/nodejs/node/blob/a91293d4d9ab403046ab5eb022332e4e3d249bd3/lib/internal/url.js#L1257 */
  
  var urlToOptions = url => {
  	const options = {
  		protocol: url.protocol,
  		hostname: typeof url.hostname === 'string' && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
  		host: url.host,
  		hash: url.hash,
  		search: url.search,
  		pathname: url.pathname,
  		href: url.href,
  		path: `${url.pathname || ''}${url.search || ''}`
  	};
  
  	if (typeof url.port === 'string' && url.port.length !== 0) {
  		options.port = Number(url.port);
  	}
  
  	if (url.username || url.password) {
  		options.auth = `${url.username || ''}:${url.password || ''}`;
  	}
  
  	return options;
  };
  
  var proxyEvents = (from, to, events) => {
  	for (const event of events) {
  		from.on(event, (...args) => to.emit(event, ...args));
  	}
  };
  
  var isRequestPseudoHeader = header => {
  	switch (header) {
  		case ':method':
  		case ':scheme':
  		case ':authority':
  		case ':path':
  			return true;
  		default:
  			return false;
  	}
  };
  
  var errors = createCommonjsModule(function (module) {
  /* istanbul ignore file: https://github.com/nodejs/node/blob/master/lib/internal/errors.js */
  
  const makeError = (Base, key, getMessage) => {
  	module.exports[key] = class NodeError extends Base {
  		constructor(...args) {
  			super(typeof getMessage === 'string' ? getMessage : getMessage(args));
  			this.name = `${super.name} [${key}]`;
  			this.code = key;
  		}
  	};
  };
  
  makeError(TypeError, 'ERR_INVALID_ARG_TYPE', args => {
  	const type = args[0].includes('.') ? 'property' : 'argument';
  
  	let valid = args[1];
  	const isManyTypes = Array.isArray(valid);
  
  	if (isManyTypes) {
  		valid = `${valid.slice(0, -1).join(', ')} or ${valid.slice(-1)}`;
  	}
  
  	return `The "${args[0]}" ${type} must be ${isManyTypes ? 'one of' : 'of'} type ${valid}. Received ${typeof args[2]}`;
  });
  
  makeError(TypeError, 'ERR_INVALID_PROTOCOL', args => {
  	return `Protocol "${args[0]}" not supported. Expected "${args[1]}"`;
  });
  
  makeError(Error, 'ERR_HTTP_HEADERS_SENT', args => {
  	return `Cannot ${args[0]} headers after they are sent to the client`;
  });
  
  makeError(TypeError, 'ERR_INVALID_HTTP_TOKEN', args => {
  	return `${args[0]} must be a valid HTTP token [${args[1]}]`;
  });
  
  makeError(TypeError, 'ERR_HTTP_INVALID_HEADER_VALUE', args => {
  	return `Invalid value "${args[0]} for header "${args[1]}"`;
  });
  
  makeError(TypeError, 'ERR_INVALID_CHAR', args => {
  	return `Invalid character in ${args[0]} [${args[1]}]`;
  });
  });
  
  const {Writable} = Stream;
  const {Agent: Agent$1, globalAgent} = agent;
  
  
  
  
  const {
  	ERR_INVALID_ARG_TYPE,
  	ERR_INVALID_PROTOCOL,
  	ERR_HTTP_HEADERS_SENT,
  	ERR_INVALID_HTTP_TOKEN,
  	ERR_HTTP_INVALID_HEADER_VALUE,
  	ERR_INVALID_CHAR
  } = errors;
  
  const {
  	HTTP2_HEADER_STATUS,
  	HTTP2_HEADER_METHOD,
  	HTTP2_HEADER_PATH,
  	HTTP2_METHOD_CONNECT
  } = http2.constants;
  
  const kHeaders = Symbol('headers');
  const kOrigin = Symbol('origin');
  const kSession = Symbol('session');
  const kOptions = Symbol('options');
  const kFlushedHeaders = Symbol('flushedHeaders');
  const kJobs = Symbol('jobs');
  
  const isValidHttpToken = /^[\^`\-\w!#$%&*+.|~]+$/;
  const isInvalidHeaderValue = /[^\t\u0020-\u007E\u0080-\u00FF]/;
  
  class ClientRequest extends Writable {
  	constructor(input, options, callback) {
  		super({
  			autoDestroy: false
  		});
  
  		const hasInput = typeof input === 'string' || input instanceof URL;
  		if (hasInput) {
  			input = urlToOptions(input instanceof URL ? input : new URL(input));
  		}
  
  		if (typeof options === 'function' || options === undefined) {
  			// (options, callback)
  			callback = options;
  			options = hasInput ? input : {...input};
  		} else {
  			// (input, options, callback)
  			options = {...input, ...options};
  		}
  
  		if (options.h2session) {
  			this[kSession] = options.h2session;
  		} else if (options.agent === false) {
  			this.agent = new Agent$1({maxFreeSessions: 0});
  		} else if (typeof options.agent === 'undefined' || options.agent === null) {
  			if (typeof options.createConnection === 'function') {
  				// This is a workaround - we don't have to create the session on our own.
  				this.agent = new Agent$1({maxFreeSessions: 0});
  				this.agent.createConnection = options.createConnection;
  			} else {
  				this.agent = globalAgent;
  			}
  		} else if (typeof options.agent.request === 'function') {
  			this.agent = options.agent;
  		} else {
  			throw new ERR_INVALID_ARG_TYPE('options.agent', ['Agent-like Object', 'undefined', 'false'], options.agent);
  		}
  
  		if (options.protocol && options.protocol !== 'https:') {
  			throw new ERR_INVALID_PROTOCOL(options.protocol, 'https:');
  		}
  
  		const port = options.port || options.defaultPort || (this.agent && this.agent.defaultPort) || 443;
  		const host = options.hostname || options.host || 'localhost';
  
  		// Don't enforce the origin via options. It may be changed in an Agent.
  		delete options.hostname;
  		delete options.host;
  		delete options.port;
  
  		const {timeout} = options;
  		options.timeout = undefined;
  
  		this[kHeaders] = Object.create(null);
  		this[kJobs] = [];
  
  		this.socket = null;
  		this.connection = null;
  
  		this.method = options.method || 'GET';
  		this.path = options.path;
  
  		this.res = null;
  		this.aborted = false;
  		this.reusedSocket = false;
  
  		if (options.headers) {
  			for (const [header, value] of Object.entries(options.headers)) {
  				this.setHeader(header, value);
  			}
  		}
  
  		if (options.auth && !('authorization' in this[kHeaders])) {
  			this[kHeaders].authorization = 'Basic ' + Buffer.from(options.auth).toString('base64');
  		}
  
  		options.session = options.tlsSession;
  		options.path = options.socketPath;
  
  		this[kOptions] = options;
  
  		// Clients that generate HTTP/2 requests directly SHOULD use the :authority pseudo-header field instead of the Host header field.
  		if (port === 443) {
  			this[kOrigin] = `https://${host}`;
  
  			if (!(':authority' in this[kHeaders])) {
  				this[kHeaders][':authority'] = host;
  			}
  		} else {
  			this[kOrigin] = `https://${host}:${port}`;
  
  			if (!(':authority' in this[kHeaders])) {
  				this[kHeaders][':authority'] = `${host}:${port}`;
  			}
  		}
  
  		if (timeout) {
  			this.setTimeout(timeout);
  		}
  
  		if (callback) {
  			this.once('response', callback);
  		}
  
  		this[kFlushedHeaders] = false;
  	}
  
  	get method() {
  		return this[kHeaders][HTTP2_HEADER_METHOD];
  	}
  
  	set method(value) {
  		if (value) {
  			this[kHeaders][HTTP2_HEADER_METHOD] = value.toUpperCase();
  		}
  	}
  
  	get path() {
  		return this[kHeaders][HTTP2_HEADER_PATH];
  	}
  
  	set path(value) {
  		if (value) {
  			this[kHeaders][HTTP2_HEADER_PATH] = value;
  		}
  	}
  
  	get _mustNotHaveABody() {
  		return this.method === 'GET' || this.method === 'HEAD' || this.method === 'DELETE';
  	}
  
  	_write(chunk, encoding, callback) {
  		// https://github.com/nodejs/node/blob/654df09ae0c5e17d1b52a900a545f0664d8c7627/lib/internal/http2/util.js#L148-L156
  		if (this._mustNotHaveABody) {
  			callback(new Error('The GET, HEAD and DELETE methods must NOT have a body'));
  			/* istanbul ignore next: Node.js 12 throws directly */
  			return;
  		}
  
  		this.flushHeaders();
  
  		const callWrite = () => this._request.write(chunk, encoding, callback);
  		if (this._request) {
  			callWrite();
  		} else {
  			this[kJobs].push(callWrite);
  		}
  	}
  
  	_final(callback) {
  		if (this.destroyed) {
  			return;
  		}
  
  		this.flushHeaders();
  
  		const callEnd = () => {
  			// For GET, HEAD and DELETE
  			if (this._mustNotHaveABody) {
  				callback();
  				return;
  			}
  
  			this._request.end(callback);
  		};
  
  		if (this._request) {
  			callEnd();
  		} else {
  			this[kJobs].push(callEnd);
  		}
  	}
  
  	abort() {
  		if (this.res && this.res.complete) {
  			return;
  		}
  
  		if (!this.aborted) {
  			process.nextTick(() => this.emit('abort'));
  		}
  
  		this.aborted = true;
  
  		this.destroy();
  	}
  
  	_destroy(error, callback) {
  		if (this.res) {
  			this.res._dump();
  		}
  
  		if (this._request) {
  			this._request.destroy();
  		}
  
  		callback(error);
  	}
  
  	async flushHeaders() {
  		if (this[kFlushedHeaders] || this.destroyed) {
  			return;
  		}
  
  		this[kFlushedHeaders] = true;
  
  		const isConnectMethod = this.method === HTTP2_METHOD_CONNECT;
  
  		// The real magic is here
  		const onStream = stream => {
  			this._request = stream;
  
  			if (this.destroyed) {
  				stream.destroy();
  				return;
  			}
  
  			// Forwards `timeout`, `continue`, `close` and `error` events to this instance.
  			if (!isConnectMethod) {
  				proxyEvents(stream, this, ['timeout', 'continue', 'close', 'error']);
  			}
  
  			// Wait for the `finish` event. We don't want to emit the `response` event
  			// before `request.end()` is called.
  			const waitForEnd = fn => {
  				return (...args) => {
  					if (!this.writable && !this.destroyed) {
  						fn(...args);
  					} else {
  						this.once('finish', () => {
  							fn(...args);
  						});
  					}
  				};
  			};
  
  			// This event tells we are ready to listen for the data.
  			stream.once('response', waitForEnd((headers, flags, rawHeaders) => {
  				// If we were to emit raw request stream, it would be as fast as the native approach.
  				// Note that wrapping the raw stream in a Proxy instance won't improve the performance (already tested it).
  				const response = new incomingMessage(this.socket, stream.readableHighWaterMark);
  				this.res = response;
  
  				response.req = this;
  				response.statusCode = headers[HTTP2_HEADER_STATUS];
  				response.headers = headers;
  				response.rawHeaders = rawHeaders;
  
  				response.once('end', () => {
  					if (this.aborted) {
  						response.aborted = true;
  						response.emit('aborted');
  					} else {
  						response.complete = true;
  
  						// Has no effect, just be consistent with the Node.js behavior
  						response.socket = null;
  						response.connection = null;
  					}
  				});
  
  				if (isConnectMethod) {
  					response.upgrade = true;
  
  					// The HTTP1 API says the socket is detached here,
  					// but we can't do that so we pass the original HTTP2 request.
  					if (this.emit('connect', response, stream, Buffer.alloc(0))) {
  						this.emit('close');
  					} else {
  						// No listeners attached, destroy the original request.
  						stream.destroy();
  					}
  				} else {
  					// Forwards data
  					stream.on('data', chunk => {
  						if (!response._dumped && !response.push(chunk)) {
  							stream.pause();
  						}
  					});
  
  					stream.once('end', () => {
  						response.push(null);
  					});
  
  					if (!this.emit('response', response)) {
  						// No listeners attached, dump the response.
  						response._dump();
  					}
  				}
  			}));
  
  			// Emits `information` event
  			stream.once('headers', waitForEnd(
  				headers => this.emit('information', {statusCode: headers[HTTP2_HEADER_STATUS]})
  			));
  
  			stream.once('trailers', waitForEnd((trailers, flags, rawTrailers) => {
  				const {res} = this;
  
  				// Assigns trailers to the response object.
  				res.trailers = trailers;
  				res.rawTrailers = rawTrailers;
  			}));
  
  			const {socket} = stream.session;
  			this.socket = socket;
  			this.connection = socket;
  
  			for (const job of this[kJobs]) {
  				job();
  			}
  
  			this.emit('socket', this.socket);
  		};
  
  		// Makes a HTTP2 request
  		if (this[kSession]) {
  			try {
  				onStream(this[kSession].request(this[kHeaders]));
  			} catch (error) {
  				this.emit('error', error);
  			}
  		} else {
  			this.reusedSocket = true;
  
  			try {
  				onStream(await this.agent.request(this[kOrigin], this[kOptions], this[kHeaders]));
  			} catch (error) {
  				this.emit('error', error);
  			}
  		}
  	}
  
  	getHeader(name) {
  		if (typeof name !== 'string') {
  			throw new ERR_INVALID_ARG_TYPE('name', 'string', name);
  		}
  
  		return this[kHeaders][name.toLowerCase()];
  	}
  
  	get headersSent() {
  		return this[kFlushedHeaders];
  	}
  
  	removeHeader(name) {
  		if (typeof name !== 'string') {
  			throw new ERR_INVALID_ARG_TYPE('name', 'string', name);
  		}
  
  		if (this.headersSent) {
  			throw new ERR_HTTP_HEADERS_SENT('remove');
  		}
  
  		delete this[kHeaders][name.toLowerCase()];
  	}
  
  	setHeader(name, value) {
  		if (this.headersSent) {
  			throw new ERR_HTTP_HEADERS_SENT('set');
  		}
  
  		if (typeof name !== 'string' || (!isValidHttpToken.test(name) && !isRequestPseudoHeader(name))) {
  			throw new ERR_INVALID_HTTP_TOKEN('Header name', name);
  		}
  
  		if (typeof value === 'undefined') {
  			throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
  		}
  
  		if (isInvalidHeaderValue.test(value)) {
  			throw new ERR_INVALID_CHAR('header content', name);
  		}
  
  		this[kHeaders][name.toLowerCase()] = value;
  	}
  
  	setNoDelay() {
  		// HTTP2 sockets cannot be malformed, do nothing.
  	}
  
  	setSocketKeepAlive() {
  		// HTTP2 sockets cannot be malformed, do nothing.
  	}
  
  	setTimeout(ms, callback) {
  		const applyTimeout = () => this._request.setTimeout(ms, callback);
  
  		if (this._request) {
  			applyTimeout();
  		} else {
  			this[kJobs].push(applyTimeout);
  		}
  
  		return this;
  	}
  
  	get maxHeadersCount() {
  		if (!this.destroyed && this._request) {
  			return this._request.session.localSettings.maxHeaderListSize;
  		}
  
  		return undefined;
  	}
  
  	set maxHeadersCount(_value) {
  		// Updating HTTP2 settings would affect all requests, do nothing.
  	}
  }
  
  var clientRequest = ClientRequest;
  
  var resolveAlpn = (options = {}) => new Promise((resolve, reject) => {
  	const socket = tls.connect(options, () => {
  		if (options.resolveSocket) {
  			socket.off('error', reject);
  			resolve({alpnProtocol: socket.alpnProtocol, socket});
  		} else {
  			socket.destroy();
  			resolve({alpnProtocol: socket.alpnProtocol});
  		}
  	});
  
  	socket.on('error', reject);
  });
  
  /* istanbul ignore file: https://github.com/nodejs/node/blob/v13.0.1/lib/_http_agent.js */
  
  var calculateServerName = options => {
  	let servername = options.host;
  	const hostHeader = options.headers && options.headers.host;
  
  	if (hostHeader) {
  		if (hostHeader.startsWith('[')) {
  			const index = hostHeader.indexOf(']');
  			if (index === -1) {
  				servername = hostHeader;
  			} else {
  				servername = hostHeader.slice(1, -1);
  			}
  		} else {
  			servername = hostHeader.split(':', 1)[0];
  		}
  	}
  
  	if (net.isIP(servername)) {
  		return '';
  	}
  
  	return servername;
  };
  
  const cache = new quickLru({maxSize: 100});
  const queue = new Map();
  
  const installSocket = (agent, socket, options) => {
  	socket._httpMessage = {shouldKeepAlive: true};
  
  	const onFree = () => {
  		agent.emit('free', socket, options);
  	};
  
  	socket.on('free', onFree);
  
  	const onClose = () => {
  		agent.removeSocket(socket, options);
  	};
  
  	socket.on('close', onClose);
  
  	const onRemove = () => {
  		agent.removeSocket(socket, options);
  		socket.off('close', onClose);
  		socket.off('free', onFree);
  		socket.off('agentRemove', onRemove);
  	};
  
  	socket.on('agentRemove', onRemove);
  
  	agent.emit('free', socket, options);
  };
  
  const resolveProtocol = async options => {
  	const name = `${options.host}:${options.port}:${options.ALPNProtocols.sort()}`;
  
  	if (!cache.has(name)) {
  		if (queue.has(name)) {
  			const result = await queue.get(name);
  			return result.alpnProtocol;
  		}
  
  		const {path, agent} = options;
  		options.path = options.socketPath;
  
  		const resultPromise = resolveAlpn(options);
  		queue.set(name, resultPromise);
  
  		try {
  			const {socket, alpnProtocol} = await resultPromise;
  			cache.set(name, alpnProtocol);
  
  			options.path = path;
  
  			if (alpnProtocol === 'h2') {
  				// https://github.com/nodejs/node/issues/33343
  				socket.destroy();
  			} else {
  				const {globalAgent} = https;
  				const defaultCreateConnection = https.Agent.prototype.createConnection;
  
  				if (agent) {
  					if (agent.createConnection === defaultCreateConnection) {
  						installSocket(agent, socket, options);
  					} else {
  						socket.destroy();
  					}
  				} else if (globalAgent.createConnection === defaultCreateConnection) {
  					installSocket(globalAgent, socket, options);
  				} else {
  					socket.destroy();
  				}
  			}
  
  			queue.delete(name);
  
  			return alpnProtocol;
  		} catch (error) {
  			queue.delete(name);
  
  			throw error;
  		}
  	}
  
  	return cache.get(name);
  };
  
  var auto = async (input, options, callback) => {
  	if (typeof input === 'string' || input instanceof URL) {
  		input = urlToOptions(new URL(input));
  	}
  
  	if (typeof options === 'function') {
  		callback = options;
  		options = undefined;
  	}
  
  	options = {
  		ALPNProtocols: ['h2', 'http/1.1'],
  		...input,
  		...options,
  		resolveSocket: true
  	};
  
  	if (!Array.isArray(options.ALPNProtocols) || options.ALPNProtocols.length === 0) {
  		throw new Error('The `ALPNProtocols` option must be an Array with at least one entry');
  	}
  
  	options.protocol = options.protocol || 'https:';
  	const isHttps = options.protocol === 'https:';
  
  	options.host = options.hostname || options.host || 'localhost';
  	options.session = options.tlsSession;
  	options.servername = options.servername || calculateServerName(options);
  	options.port = options.port || (isHttps ? 443 : 80);
  	options._defaultAgent = isHttps ? https.globalAgent : http.globalAgent;
  
  	const agents = options.agent;
  
  	if (agents) {
  		if (agents.addRequest) {
  			throw new Error('The `options.agent` object can contain only `http`, `https` or `http2` properties');
  		}
  
  		options.agent = agents[isHttps ? 'https' : 'http'];
  	}
  
  	if (isHttps) {
  		const protocol = await resolveProtocol(options);
  
  		if (protocol === 'h2') {
  			if (agents) {
  				options.agent = agents.http2;
  			}
  
  			return new clientRequest(options, callback);
  		}
  	}
  
  	return http.request(options, callback);
  };
  
  var protocolCache = cache;
  auto.protocolCache = protocolCache;
  
  const request = (url, options, callback) => {
  	return new clientRequest(url, options, callback);
  };
  
  const get = (url, options, callback) => {
  	// eslint-disable-next-line unicorn/prevent-abbreviations
  	const req = new clientRequest(url, options, callback);
  	req.end();
  
  	return req;
  };
  
  var source$3 = {
  	...http2,
  	ClientRequest: clientRequest,
  	IncomingMessage: incomingMessage,
  	...agent,
  	request,
  	get,
  	auto
  };
  
  var isFormData = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  exports.default = (body) => dist.default.nodeStream(body) && dist.default.function_(body.getBoundary);
  });
  
  var getBodySize = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  
  
  
  const statAsync = util.promisify(fs.stat);
  exports.default = async (body, headers) => {
      if (headers && 'content-length' in headers) {
          return Number(headers['content-length']);
      }
      if (!body) {
          return 0;
      }
      if (dist.default.string(body)) {
          return Buffer.byteLength(body);
      }
      if (dist.default.buffer(body)) {
          return body.length;
      }
      if (isFormData.default(body)) {
          return util.promisify(body.getLength.bind(body))();
      }
      if (body instanceof fs.ReadStream) {
          const { size } = await statAsync(body.path);
          if (size === 0) {
              return undefined;
          }
          return size;
      }
      return undefined;
  };
  });
  
  var proxyEvents$1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  function default_1(from, to, events) {
      const fns = {};
      for (const event of events) {
          fns[event] = (...args) => {
              to.emit(event, ...args);
          };
          from.on(event, fns[event]);
      }
      return () => {
          for (const event of events) {
              from.off(event, fns[event]);
          }
      };
  }
  exports.default = default_1;
  });
  
  var unhandle = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  // When attaching listeners, it's very easy to forget about them.
  // Especially if you do error handling and set timeouts.
  // So instead of checking if it's proper to throw an error on every timeout ever,
  // use this simple tool which will remove all listeners you have attached.
  exports.default = () => {
      const handlers = [];
      return {
          once(origin, event, fn) {
              origin.once(event, fn);
              handlers.push({ origin, event, fn });
          },
          unhandleAll() {
              for (const handler of handlers) {
                  const { origin, event, fn } = handler;
                  origin.removeListener(event, fn);
              }
              handlers.length = 0;
          }
      };
  };
  });
  
  var timedOut = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.TimeoutError = void 0;
  
  
  const reentry = Symbol('reentry');
  const noop = () => { };
  class TimeoutError extends Error {
      constructor(threshold, event) {
          super(`Timeout awaiting '${event}' for ${threshold}ms`);
          this.event = event;
          this.name = 'TimeoutError';
          this.code = 'ETIMEDOUT';
      }
  }
  exports.TimeoutError = TimeoutError;
  exports.default = (request, delays, options) => {
      if (reentry in request) {
          return noop;
      }
      request[reentry] = true;
      const cancelers = [];
      const { once, unhandleAll } = unhandle.default();
      const addTimeout = (delay, callback, event) => {
          var _a;
          const timeout = setTimeout(callback, delay, delay, event);
          (_a = timeout.unref) === null || _a === void 0 ? void 0 : _a.call(timeout);
          const cancel = () => {
              clearTimeout(timeout);
          };
          cancelers.push(cancel);
          return cancel;
      };
      const { host, hostname } = options;
      const timeoutHandler = (delay, event) => {
          request.destroy(new TimeoutError(delay, event));
      };
      const cancelTimeouts = () => {
          for (const cancel of cancelers) {
              cancel();
          }
          unhandleAll();
      };
      request.once('error', error => {
          cancelTimeouts();
          // Save original behavior
          /* istanbul ignore next */
          if (request.listenerCount('error') === 0) {
              throw error;
          }
      });
      request.once('close', cancelTimeouts);
      once(request, 'response', (response) => {
          once(response, 'end', cancelTimeouts);
      });
      if (typeof delays.request !== 'undefined') {
          addTimeout(delays.request, timeoutHandler, 'request');
      }
      if (typeof delays.socket !== 'undefined') {
          const socketTimeoutHandler = () => {
              timeoutHandler(delays.socket, 'socket');
          };
          request.setTimeout(delays.socket, socketTimeoutHandler);
          // `request.setTimeout(0)` causes a memory leak.
          // We can just remove the listener and forget about the timer - it's unreffed.
          // See https://github.com/sindresorhus/got/issues/690
          cancelers.push(() => {
              request.removeListener('timeout', socketTimeoutHandler);
          });
      }
      once(request, 'socket', (socket) => {
          var _a;
          const { socketPath } = request;
          /* istanbul ignore next: hard to test */
          if (socket.connecting) {
              const hasPath = Boolean(socketPath !== null && socketPath !== void 0 ? socketPath : net.isIP((_a = hostname !== null && hostname !== void 0 ? hostname : host) !== null && _a !== void 0 ? _a : '') !== 0);
              if (typeof delays.lookup !== 'undefined' && !hasPath && typeof socket.address().address === 'undefined') {
                  const cancelTimeout = addTimeout(delays.lookup, timeoutHandler, 'lookup');
                  once(socket, 'lookup', cancelTimeout);
              }
              if (typeof delays.connect !== 'undefined') {
                  const timeConnect = () => addTimeout(delays.connect, timeoutHandler, 'connect');
                  if (hasPath) {
                      once(socket, 'connect', timeConnect());
                  }
                  else {
                      once(socket, 'lookup', (error) => {
                          if (error === null) {
                              once(socket, 'connect', timeConnect());
                          }
                      });
                  }
              }
              if (typeof delays.secureConnect !== 'undefined' && options.protocol === 'https:') {
                  once(socket, 'connect', () => {
                      const cancelTimeout = addTimeout(delays.secureConnect, timeoutHandler, 'secureConnect');
                      once(socket, 'secureConnect', cancelTimeout);
                  });
              }
          }
          if (typeof delays.send !== 'undefined') {
              const timeRequest = () => addTimeout(delays.send, timeoutHandler, 'send');
              /* istanbul ignore next: hard to test */
              if (socket.connecting) {
                  once(socket, 'connect', () => {
                      once(request, 'upload-complete', timeRequest());
                  });
              }
              else {
                  once(request, 'upload-complete', timeRequest());
              }
          }
      });
      if (typeof delays.response !== 'undefined') {
          once(request, 'upload-complete', () => {
              const cancelTimeout = addTimeout(delays.response, timeoutHandler, 'response');
              once(request, 'response', cancelTimeout);
          });
      }
      return cancelTimeouts;
  };
  });
  
  var urlToOptions$1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  exports.default = (url) => {
      // Cast to URL
      url = url;
      const options = {
          protocol: url.protocol,
          hostname: dist.default.string(url.hostname) && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
          host: url.host,
          hash: url.hash,
          search: url.search,
          pathname: url.pathname,
          href: url.href,
          path: `${url.pathname || ''}${url.search || ''}`
      };
      if (dist.default.string(url.port) && url.port.length > 0) {
          options.port = Number(url.port);
      }
      if (url.username || url.password) {
          options.auth = `${url.username || ''}:${url.password || ''}`;
      }
      return options;
  };
  });
  
  var optionsToUrl = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  /* istanbul ignore file: deprecated */
  
  const keys = [
      'protocol',
      'host',
      'hostname',
      'port',
      'pathname',
      'search'
  ];
  exports.default = (origin, options) => {
      var _a, _b;
      if (options.path) {
          if (options.pathname) {
              throw new TypeError('Parameters `path` and `pathname` are mutually exclusive.');
          }
          if (options.search) {
              throw new TypeError('Parameters `path` and `search` are mutually exclusive.');
          }
          if (options.searchParams) {
              throw new TypeError('Parameters `path` and `searchParams` are mutually exclusive.');
          }
      }
      if (options.search && options.searchParams) {
          throw new TypeError('Parameters `search` and `searchParams` are mutually exclusive.');
      }
      if (!origin) {
          if (!options.protocol) {
              throw new TypeError('No URL protocol specified');
          }
          origin = `${options.protocol}//${(_b = (_a = options.hostname) !== null && _a !== void 0 ? _a : options.host) !== null && _b !== void 0 ? _b : ''}`;
      }
      const url = new Url.URL(origin);
      if (options.path) {
          const searchIndex = options.path.indexOf('?');
          if (searchIndex === -1) {
              options.pathname = options.path;
          }
          else {
              options.pathname = options.path.slice(0, searchIndex);
              options.search = options.path.slice(searchIndex + 1);
          }
          delete options.path;
      }
      for (const key of keys) {
          if (options[key]) {
              url[key] = options[key].toString();
          }
      }
      return url;
  };
  });
  
  var weakableMap = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  class WeakableMap {
      constructor() {
          this.weakMap = new WeakMap();
          this.map = new Map();
      }
      set(key, value) {
          if (typeof key === 'object') {
              this.weakMap.set(key, value);
          }
          else {
              this.map.set(key, value);
          }
      }
      get(key) {
          if (typeof key === 'object') {
              return this.weakMap.get(key);
          }
          return this.map.get(key);
      }
      has(key) {
          if (typeof key === 'object') {
              return this.weakMap.has(key);
          }
          return this.map.has(key);
      }
  }
  exports.default = WeakableMap;
  });
  
  var getBuffer_1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  // TODO: Update https://github.com/sindresorhus/get-stream
  const getBuffer = async (stream) => {
      const chunks = [];
      let length = 0;
      for await (const chunk of stream) {
          chunks.push(chunk);
          length += Buffer.byteLength(chunk);
      }
      if (Buffer.isBuffer(chunks[0])) {
          return Buffer.concat(chunks, length);
      }
      return Buffer.from(chunks.join(''));
  };
  exports.default = getBuffer;
  });
  
  var dnsIpVersion = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.dnsLookupIpVersionToFamily = exports.isDnsLookupIpVersion = void 0;
  const conversionTable = {
      auto: 0,
      ipv4: 4,
      ipv6: 6
  };
  exports.isDnsLookupIpVersion = (value) => {
      return value in conversionTable;
  };
  exports.dnsLookupIpVersionToFamily = (dnsLookupIpVersion) => {
      if (exports.isDnsLookupIpVersion(dnsLookupIpVersion)) {
          return conversionTable[dnsLookupIpVersion];
      }
      throw new Error('Invalid DNS lookup IP version');
  };
  });
  
  var isResponseOk = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.isResponseOk = void 0;
  exports.isResponseOk = (response) => {
      const { statusCode } = response;
      const limitStatusCode = response.request.options.followRedirect ? 299 : 399;
      return (statusCode >= 200 && statusCode <= limitStatusCode) || statusCode === 304;
  };
  });
  
  var deprecationWarning = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  const alreadyWarned = new Set();
  exports.default = (message) => {
      if (alreadyWarned.has(message)) {
          return;
      }
      alreadyWarned.add(message);
      // @ts-expect-error Missing types.
      process.emitWarning(`Got: ${message}`, {
          type: 'DeprecationWarning'
      });
  };
  });
  
  var normalizeArguments_1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  const normalizeArguments = (options, defaults) => {
      if (dist.default.null_(options.encoding)) {
          throw new TypeError('To get a Buffer, set `options.responseType` to `buffer` instead');
      }
      dist.assert.any([dist.default.string, dist.default.undefined], options.encoding);
      dist.assert.any([dist.default.boolean, dist.default.undefined], options.resolveBodyOnly);
      dist.assert.any([dist.default.boolean, dist.default.undefined], options.methodRewriting);
      dist.assert.any([dist.default.boolean, dist.default.undefined], options.isStream);
      dist.assert.any([dist.default.string, dist.default.undefined], options.responseType);
      // `options.responseType`
      if (options.responseType === undefined) {
          options.responseType = 'text';
      }
      // `options.retry`
      const { retry } = options;
      if (defaults) {
          options.retry = { ...defaults.retry };
      }
      else {
          options.retry = {
              calculateDelay: retryObject => retryObject.computedValue,
              limit: 0,
              methods: [],
              statusCodes: [],
              errorCodes: [],
              maxRetryAfter: undefined
          };
      }
      if (dist.default.object(retry)) {
          options.retry = {
              ...options.retry,
              ...retry
          };
          options.retry.methods = [...new Set(options.retry.methods.map(method => method.toUpperCase()))];
          options.retry.statusCodes = [...new Set(options.retry.statusCodes)];
          options.retry.errorCodes = [...new Set(options.retry.errorCodes)];
      }
      else if (dist.default.number(retry)) {
          options.retry.limit = retry;
      }
      if (dist.default.undefined(options.retry.maxRetryAfter)) {
          options.retry.maxRetryAfter = Math.min(
          // TypeScript is not smart enough to handle `.filter(x => is.number(x))`.
          // eslint-disable-next-line unicorn/no-fn-reference-in-iterator
          ...[options.timeout.request, options.timeout.connect].filter(dist.default.number));
      }
      // `options.pagination`
      if (dist.default.object(options.pagination)) {
          if (defaults) {
              options.pagination = {
                  ...defaults.pagination,
                  ...options.pagination
              };
          }
          const { pagination } = options;
          if (!dist.default.function_(pagination.transform)) {
              throw new Error('`options.pagination.transform` must be implemented');
          }
          if (!dist.default.function_(pagination.shouldContinue)) {
              throw new Error('`options.pagination.shouldContinue` must be implemented');
          }
          if (!dist.default.function_(pagination.filter)) {
              throw new TypeError('`options.pagination.filter` must be implemented');
          }
          if (!dist.default.function_(pagination.paginate)) {
              throw new Error('`options.pagination.paginate` must be implemented');
          }
      }
      // JSON mode
      if (options.responseType === 'json' && options.headers.accept === undefined) {
          options.headers.accept = 'application/json';
      }
      return options;
  };
  exports.default = normalizeArguments;
  });
  
  var calculateRetryDelay_1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.retryAfterStatusCodes = void 0;
  exports.retryAfterStatusCodes = new Set([413, 429, 503]);
  const calculateRetryDelay = ({ attemptCount, retryOptions, error, retryAfter }) => {
      if (attemptCount > retryOptions.limit) {
          return 0;
      }
      const hasMethod = retryOptions.methods.includes(error.options.method);
      const hasErrorCode = retryOptions.errorCodes.includes(error.code);
      const hasStatusCode = error.response && retryOptions.statusCodes.includes(error.response.statusCode);
      if (!hasMethod || (!hasErrorCode && !hasStatusCode)) {
          return 0;
      }
      if (error.response) {
          if (retryAfter) {
              if (retryOptions.maxRetryAfter === undefined || retryAfter > retryOptions.maxRetryAfter) {
                  return 0;
              }
              return retryAfter;
          }
          if (error.response.statusCode === 413) {
              return 0;
          }
      }
      const noise = Math.random() * 100;
      return ((2 ** (attemptCount - 1)) * 1000) + noise;
  };
  exports.default = calculateRetryDelay;
  });
  
  var core$2 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.UnsupportedProtocolError = exports.ReadError = exports.TimeoutError = exports.UploadError = exports.CacheError = exports.HTTPError = exports.MaxRedirectsError = exports.RequestError = exports.setNonEnumerableProperties = exports.knownHookEvents = exports.withoutBody = exports.kIsNormalizedAlready = void 0;
  
  
  
  
  
  const http_1 = http;
  
  
  
  
  
  // @ts-expect-error Missing types
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  const globalDnsCache = new source$2.default();
  const kRequest = Symbol('request');
  const kResponse = Symbol('response');
  const kResponseSize = Symbol('responseSize');
  const kDownloadedSize = Symbol('downloadedSize');
  const kBodySize = Symbol('bodySize');
  const kUploadedSize = Symbol('uploadedSize');
  const kServerResponsesPiped = Symbol('serverResponsesPiped');
  const kUnproxyEvents = Symbol('unproxyEvents');
  const kIsFromCache = Symbol('isFromCache');
  const kCancelTimeouts = Symbol('cancelTimeouts');
  const kStartedReading = Symbol('startedReading');
  const kStopReading = Symbol('stopReading');
  const kTriggerRead = Symbol('triggerRead');
  const kBody = Symbol('body');
  const kJobs = Symbol('jobs');
  const kOriginalResponse = Symbol('originalResponse');
  const kRetryTimeout = Symbol('retryTimeout');
  exports.kIsNormalizedAlready = Symbol('isNormalizedAlready');
  const supportsBrotli = dist.default.string(process.versions.brotli);
  exports.withoutBody = new Set(['GET', 'HEAD']);
  exports.knownHookEvents = [
      'init',
      'beforeRequest',
      'beforeRedirect',
      'beforeError',
      'beforeRetry',
      // Promise-Only
      'afterResponse'
  ];
  function validateSearchParameters(searchParameters) {
      // eslint-disable-next-line guard-for-in
      for (const key in searchParameters) {
          const value = searchParameters[key];
          if (!dist.default.string(value) && !dist.default.number(value) && !dist.default.boolean(value) && !dist.default.null_(value) && !dist.default.undefined(value)) {
              throw new TypeError(`The \`searchParams\` value '${String(value)}' must be a string, number, boolean or null`);
          }
      }
  }
  function isClientRequest(clientRequest) {
      return dist.default.object(clientRequest) && !('statusCode' in clientRequest);
  }
  const cacheableStore = new weakableMap.default();
  const waitForOpenFile = async (file) => new Promise((resolve, reject) => {
      const onError = (error) => {
          reject(error);
      };
      // Node.js 12 has incomplete types
      if (!file.pending) {
          resolve();
      }
      file.once('error', onError);
      file.once('ready', () => {
          file.off('error', onError);
          resolve();
      });
  });
  const redirectCodes = new Set([300, 301, 302, 303, 304, 307, 308]);
  const nonEnumerableProperties = [
      'context',
      'body',
      'json',
      'form'
  ];
  exports.setNonEnumerableProperties = (sources, to) => {
      // Non enumerable properties shall not be merged
      const properties = {};
      for (const source of sources) {
          if (!source) {
              continue;
          }
          for (const name of nonEnumerableProperties) {
              if (!(name in source)) {
                  continue;
              }
              properties[name] = {
                  writable: true,
                  configurable: true,
                  enumerable: false,
                  // @ts-expect-error TS doesn't see the check above
                  value: source[name]
              };
          }
      }
      Object.defineProperties(to, properties);
  };
  /**
  An error to be thrown when a request fails.
  Contains a `code` property with error class code, like `ECONNREFUSED`.
  */
  class RequestError extends Error {
      constructor(message, error, self) {
          var _a;
          super(message);
          Error.captureStackTrace(this, this.constructor);
          this.name = 'RequestError';
          this.code = error.code;
          if (self instanceof Request) {
              Object.defineProperty(this, 'request', {
                  enumerable: false,
                  value: self
              });
              Object.defineProperty(this, 'response', {
                  enumerable: false,
                  value: self[kResponse]
              });
              Object.defineProperty(this, 'options', {
                  // This fails because of TS 3.7.2 useDefineForClassFields
                  // Ref: https://github.com/microsoft/TypeScript/issues/34972
                  enumerable: false,
                  value: self.options
              });
          }
          else {
              Object.defineProperty(this, 'options', {
                  // This fails because of TS 3.7.2 useDefineForClassFields
                  // Ref: https://github.com/microsoft/TypeScript/issues/34972
                  enumerable: false,
                  value: self
              });
          }
          this.timings = (_a = this.request) === null || _a === void 0 ? void 0 : _a.timings;
          // Recover the original stacktrace
          if (!dist.default.undefined(error.stack)) {
              const indexOfMessage = this.stack.indexOf(this.message) + this.message.length;
              const thisStackTrace = this.stack.slice(indexOfMessage).split('\n').reverse();
              const errorStackTrace = error.stack.slice(error.stack.indexOf(error.message) + error.message.length).split('\n').reverse();
              // Remove duplicated traces
              while (errorStackTrace.length !== 0 && errorStackTrace[0] === thisStackTrace[0]) {
                  thisStackTrace.shift();
              }
              this.stack = `${this.stack.slice(0, indexOfMessage)}${thisStackTrace.reverse().join('\n')}${errorStackTrace.reverse().join('\n')}`;
          }
      }
  }
  exports.RequestError = RequestError;
  /**
  An error to be thrown when the server redirects you more than ten times.
  Includes a `response` property.
  */
  class MaxRedirectsError extends RequestError {
      constructor(request) {
          super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
          this.name = 'MaxRedirectsError';
      }
  }
  exports.MaxRedirectsError = MaxRedirectsError;
  /**
  An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304.
  Includes a `response` property.
  */
  class HTTPError extends RequestError {
      constructor(response) {
          super(`Response code ${response.statusCode} (${response.statusMessage})`, {}, response.request);
          this.name = 'HTTPError';
      }
  }
  exports.HTTPError = HTTPError;
  /**
  An error to be thrown when a cache method fails.
  For example, if the database goes down or there's a filesystem error.
  */
  class CacheError extends RequestError {
      constructor(error, request) {
          super(error.message, error, request);
          this.name = 'CacheError';
      }
  }
  exports.CacheError = CacheError;
  /**
  An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
  */
  class UploadError extends RequestError {
      constructor(error, request) {
          super(error.message, error, request);
          this.name = 'UploadError';
      }
  }
  exports.UploadError = UploadError;
  /**
  An error to be thrown when the request is aborted due to a timeout.
  Includes an `event` and `timings` property.
  */
  class TimeoutError extends RequestError {
      constructor(error, timings, request) {
          super(error.message, error, request);
          this.name = 'TimeoutError';
          this.event = error.event;
          this.timings = timings;
      }
  }
  exports.TimeoutError = TimeoutError;
  /**
  An error to be thrown when reading from response stream fails.
  */
  class ReadError extends RequestError {
      constructor(error, request) {
          super(error.message, error, request);
          this.name = 'ReadError';
      }
  }
  exports.ReadError = ReadError;
  /**
  An error to be thrown when given an unsupported protocol.
  */
  class UnsupportedProtocolError extends RequestError {
      constructor(options) {
          super(`Unsupported protocol "${options.url.protocol}"`, {}, options);
          this.name = 'UnsupportedProtocolError';
      }
  }
  exports.UnsupportedProtocolError = UnsupportedProtocolError;
  const proxiedRequestEvents = [
      'socket',
      'connect',
      'continue',
      'information',
      'upgrade',
      'timeout'
  ];
  class Request extends Stream.Duplex {
      constructor(url, options = {}, defaults) {
          super({
              // This must be false, to enable throwing after destroy
              // It is used for retry logic in Promise API
              autoDestroy: false,
              // It needs to be zero because we're just proxying the data to another stream
              highWaterMark: 0
          });
          this[kDownloadedSize] = 0;
          this[kUploadedSize] = 0;
          this.requestInitialized = false;
          this[kServerResponsesPiped] = new Set();
          this.redirects = [];
          this[kStopReading] = false;
          this[kTriggerRead] = false;
          this[kJobs] = [];
          this.retryCount = 0;
          // TODO: Remove this when targeting Node.js >= 12
          this._progressCallbacks = [];
          const unlockWrite = () => this._unlockWrite();
          const lockWrite = () => this._lockWrite();
          this.on('pipe', (source) => {
              source.prependListener('data', unlockWrite);
              source.on('data', lockWrite);
              source.prependListener('end', unlockWrite);
              source.on('end', lockWrite);
          });
          this.on('unpipe', (source) => {
              source.off('data', unlockWrite);
              source.off('data', lockWrite);
              source.off('end', unlockWrite);
              source.off('end', lockWrite);
          });
          this.on('pipe', source => {
              if (source instanceof http_1.IncomingMessage) {
                  this.options.headers = {
                      ...source.headers,
                      ...this.options.headers
                  };
              }
          });
          const { json, body, form } = options;
          if (json || body || form) {
              this._lockWrite();
          }
          if (exports.kIsNormalizedAlready in options) {
              this.options = options;
          }
          else {
              try {
                  // @ts-expect-error Common TypeScript bug saying that `this.constructor` is not accessible
                  this.options = this.constructor.normalizeArguments(url, options, defaults);
              }
              catch (error) {
                  // TODO: Move this to `_destroy()`
                  if (dist.default.nodeStream(options.body)) {
                      options.body.destroy();
                  }
                  this.destroy(error);
                  return;
              }
          }
          (async () => {
              var _a;
              try {
                  if (this.options.body instanceof fs.ReadStream) {
                      await waitForOpenFile(this.options.body);
                  }
                  const { url: normalizedURL } = this.options;
                  if (!normalizedURL) {
                      throw new TypeError('Missing `url` property');
                  }
                  this.requestUrl = normalizedURL.toString();
                  decodeURI(this.requestUrl);
                  await this._finalizeBody();
                  await this._makeRequest();
                  if (this.destroyed) {
                      (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.destroy();
                      return;
                  }
                  // Queued writes etc.
                  for (const job of this[kJobs]) {
                      job();
                  }
                  // Prevent memory leak
                  this[kJobs].length = 0;
                  this.requestInitialized = true;
              }
              catch (error) {
                  if (error instanceof RequestError) {
                      this._beforeError(error);
                      return;
                  }
                  // This is a workaround for https://github.com/nodejs/node/issues/33335
                  if (!this.destroyed) {
                      this.destroy(error);
                  }
              }
          })();
      }
      static normalizeArguments(url, options, defaults) {
          var _a, _b, _c, _d, _e;
          const rawOptions = options;
          if (dist.default.object(url) && !dist.default.urlInstance(url)) {
              options = { ...defaults, ...url, ...options };
          }
          else {
              if (url && options && options.url !== undefined) {
                  throw new TypeError('The `url` option is mutually exclusive with the `input` argument');
              }
              options = { ...defaults, ...options };
              if (url !== undefined) {
                  options.url = url;
              }
              if (dist.default.urlInstance(options.url)) {
                  options.url = new Url.URL(options.url.toString());
              }
          }
          // TODO: Deprecate URL options in Got 12.
          // Support extend-specific options
          if (options.cache === false) {
              options.cache = undefined;
          }
          if (options.dnsCache === false) {
              options.dnsCache = undefined;
          }
          // Nice type assertions
          dist.assert.any([dist.default.string, dist.default.undefined], options.method);
          dist.assert.any([dist.default.object, dist.default.undefined], options.headers);
          dist.assert.any([dist.default.string, dist.default.urlInstance, dist.default.undefined], options.prefixUrl);
          dist.assert.any([dist.default.object, dist.default.undefined], options.cookieJar);
          dist.assert.any([dist.default.object, dist.default.string, dist.default.undefined], options.searchParams);
          dist.assert.any([dist.default.object, dist.default.string, dist.default.undefined], options.cache);
          dist.assert.any([dist.default.object, dist.default.number, dist.default.undefined], options.timeout);
          dist.assert.any([dist.default.object, dist.default.undefined], options.context);
          dist.assert.any([dist.default.object, dist.default.undefined], options.hooks);
          dist.assert.any([dist.default.boolean, dist.default.undefined], options.decompress);
          dist.assert.any([dist.default.boolean, dist.default.undefined], options.ignoreInvalidCookies);
          dist.assert.any([dist.default.boolean, dist.default.undefined], options.followRedirect);
          dist.assert.any([dist.default.number, dist.default.undefined], options.maxRedirects);
          dist.assert.any([dist.default.boolean, dist.default.undefined], options.throwHttpErrors);
          dist.assert.any([dist.default.boolean, dist.default.undefined], options.http2);
          dist.assert.any([dist.default.boolean, dist.default.undefined], options.allowGetBody);
          dist.assert.any([dist.default.string, dist.default.undefined], options.localAddress);
          dist.assert.any([dnsIpVersion.isDnsLookupIpVersion, dist.default.undefined], options.dnsLookupIpVersion);
          dist.assert.any([dist.default.object, dist.default.undefined], options.https);
          dist.assert.any([dist.default.boolean, dist.default.undefined], options.rejectUnauthorized);
          if (options.https) {
              dist.assert.any([dist.default.boolean, dist.default.undefined], options.https.rejectUnauthorized);
              dist.assert.any([dist.default.function_, dist.default.undefined], options.https.checkServerIdentity);
              dist.assert.any([dist.default.string, dist.default.object, dist.default.array, dist.default.undefined], options.https.certificateAuthority);
              dist.assert.any([dist.default.string, dist.default.object, dist.default.array, dist.default.undefined], options.https.key);
              dist.assert.any([dist.default.string, dist.default.object, dist.default.array, dist.default.undefined], options.https.certificate);
              dist.assert.any([dist.default.string, dist.default.undefined], options.https.passphrase);
              dist.assert.any([dist.default.string, dist.default.buffer, dist.default.array, dist.default.undefined], options.https.pfx);
          }
          dist.assert.any([dist.default.object, dist.default.undefined], options.cacheOptions);
          // `options.method`
          if (dist.default.string(options.method)) {
              options.method = options.method.toUpperCase();
          }
          else {
              options.method = 'GET';
          }
          // `options.headers`
          if (options.headers === (defaults === null || defaults === void 0 ? void 0 : defaults.headers)) {
              options.headers = { ...options.headers };
          }
          else {
              options.headers = lowercaseKeys({ ...(defaults === null || defaults === void 0 ? void 0 : defaults.headers), ...options.headers });
          }
          // Disallow legacy `url.Url`
          if ('slashes' in options) {
              throw new TypeError('The legacy `url.Url` has been deprecated. Use `URL` instead.');
          }
          // `options.auth`
          if ('auth' in options) {
              throw new TypeError('Parameter `auth` is deprecated. Use `username` / `password` instead.');
          }
          // `options.searchParams`
          if ('searchParams' in options) {
              if (options.searchParams && options.searchParams !== (defaults === null || defaults === void 0 ? void 0 : defaults.searchParams)) {
                  let searchParameters;
                  if (dist.default.string(options.searchParams) || (options.searchParams instanceof Url.URLSearchParams)) {
                      searchParameters = new Url.URLSearchParams(options.searchParams);
                  }
                  else {
                      validateSearchParameters(options.searchParams);
                      searchParameters = new Url.URLSearchParams();
                      // eslint-disable-next-line guard-for-in
                      for (const key in options.searchParams) {
                          const value = options.searchParams[key];
                          if (value === null) {
                              searchParameters.append(key, '');
                          }
                          else if (value !== undefined) {
                              searchParameters.append(key, value);
                          }
                      }
                  }
                  // `normalizeArguments()` is also used to merge options
                  (_a = defaults === null || defaults === void 0 ? void 0 : defaults.searchParams) === null || _a === void 0 ? void 0 : _a.forEach((value, key) => {
                      // Only use default if one isn't already defined
                      if (!searchParameters.has(key)) {
                          searchParameters.append(key, value);
                      }
                  });
                  options.searchParams = searchParameters;
              }
          }
          // `options.username` & `options.password`
          options.username = (_b = options.username) !== null && _b !== void 0 ? _b : '';
          options.password = (_c = options.password) !== null && _c !== void 0 ? _c : '';
          // `options.prefixUrl` & `options.url`
          if (dist.default.undefined(options.prefixUrl)) {
              options.prefixUrl = (_d = defaults === null || defaults === void 0 ? void 0 : defaults.prefixUrl) !== null && _d !== void 0 ? _d : '';
          }
          else {
              options.prefixUrl = options.prefixUrl.toString();
              if (options.prefixUrl !== '' && !options.prefixUrl.endsWith('/')) {
                  options.prefixUrl += '/';
              }
          }
          if (dist.default.string(options.url)) {
              if (options.url.startsWith('/')) {
                  throw new Error('`input` must not start with a slash when using `prefixUrl`');
              }
              options.url = optionsToUrl.default(options.prefixUrl + options.url, options);
          }
          else if ((dist.default.undefined(options.url) && options.prefixUrl !== '') || options.protocol) {
              options.url = optionsToUrl.default(options.prefixUrl, options);
          }
          if (options.url) {
              if ('port' in options) {
                  delete options.port;
              }
              // Make it possible to change `options.prefixUrl`
              let { prefixUrl } = options;
              Object.defineProperty(options, 'prefixUrl', {
                  set: (value) => {
                      const url = options.url;
                      if (!url.href.startsWith(value)) {
                          throw new Error(`Cannot change \`prefixUrl\` from ${prefixUrl} to ${value}: ${url.href}`);
                      }
                      options.url = new Url.URL(value + url.href.slice(prefixUrl.length));
                      prefixUrl = value;
                  },
                  get: () => prefixUrl
              });
              // Support UNIX sockets
              let { protocol } = options.url;
              if (protocol === 'unix:') {
                  protocol = 'http:';
                  options.url = new Url.URL(`http://unix${options.url.pathname}${options.url.search}`);
              }
              // Set search params
              if (options.searchParams) {
                  // eslint-disable-next-line @typescript-eslint/no-base-to-string
                  options.url.search = options.searchParams.toString();
              }
              // Protocol check
              if (protocol !== 'http:' && protocol !== 'https:') {
                  throw new UnsupportedProtocolError(options);
              }
              // Update `username`
              if (options.username === '') {
                  options.username = options.url.username;
              }
              else {
                  options.url.username = options.username;
              }
              // Update `password`
              if (options.password === '') {
                  options.password = options.url.password;
              }
              else {
                  options.url.password = options.password;
              }
          }
          // `options.cookieJar`
          const { cookieJar } = options;
          if (cookieJar) {
              let { setCookie, getCookieString } = cookieJar;
              dist.assert.function_(setCookie);
              dist.assert.function_(getCookieString);
              /* istanbul ignore next: Horrible `tough-cookie` v3 check */
              if (setCookie.length === 4 && getCookieString.length === 0) {
                  setCookie = util.promisify(setCookie.bind(options.cookieJar));
                  getCookieString = util.promisify(getCookieString.bind(options.cookieJar));
                  options.cookieJar = {
                      setCookie,
                      getCookieString: getCookieString
                  };
              }
          }
          // `options.cache`
          const { cache } = options;
          if (cache) {
              if (!cacheableStore.has(cache)) {
                  cacheableStore.set(cache, new src$3(((requestOptions, handler) => {
                      const result = requestOptions[kRequest](requestOptions, handler);
                      // TODO: remove this when `cacheable-request` supports async request functions.
                      if (dist.default.promise(result)) {
                          // @ts-expect-error
                          // We only need to implement the error handler in order to support HTTP2 caching.
                          // The result will be a promise anyway.
                          result.once = (event, handler) => {
                              if (event === 'error') {
                                  result.catch(handler);
                              }
                              else if (event === 'abort') {
                                  // The empty catch is needed here in case when
                                  // it rejects before it's `await`ed in `_makeRequest`.
                                  (async () => {
                                      try {
                                          const request = (await result);
                                          request.once('abort', handler);
                                      }
                                      catch (_a) { }
                                  })();
                              }
                              else {
                                  /* istanbul ignore next: safety check */
                                  throw new Error(`Unknown HTTP2 promise event: ${event}`);
                              }
                              return result;
                          };
                      }
                      return result;
                  }), cache));
              }
          }
          // `options.cacheOptions`
          options.cacheOptions = { ...options.cacheOptions };
          // `options.dnsCache`
          if (options.dnsCache === true) {
              options.dnsCache = globalDnsCache;
          }
          else if (!dist.default.undefined(options.dnsCache) && !options.dnsCache.lookup) {
              throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${dist.default(options.dnsCache)}`);
          }
          // `options.timeout`
          if (dist.default.number(options.timeout)) {
              options.timeout = { request: options.timeout };
          }
          else if (defaults && options.timeout !== defaults.timeout) {
              options.timeout = {
                  ...defaults.timeout,
                  ...options.timeout
              };
          }
          else {
              options.timeout = { ...options.timeout };
          }
          // `options.context`
          if (!options.context) {
              options.context = {};
          }
          // `options.hooks`
          const areHooksDefault = options.hooks === (defaults === null || defaults === void 0 ? void 0 : defaults.hooks);
          options.hooks = { ...options.hooks };
          for (const event of exports.knownHookEvents) {
              if (event in options.hooks) {
                  if (dist.default.array(options.hooks[event])) {
                      // See https://github.com/microsoft/TypeScript/issues/31445#issuecomment-576929044
                      options.hooks[event] = [...options.hooks[event]];
                  }
                  else {
                      throw new TypeError(`Parameter \`${event}\` must be an Array, got ${dist.default(options.hooks[event])}`);
                  }
              }
              else {
                  options.hooks[event] = [];
              }
          }
          if (defaults && !areHooksDefault) {
              for (const event of exports.knownHookEvents) {
                  const defaultHooks = defaults.hooks[event];
                  if (defaultHooks.length > 0) {
                      // See https://github.com/microsoft/TypeScript/issues/31445#issuecomment-576929044
                      options.hooks[event] = [
                          ...defaults.hooks[event],
                          ...options.hooks[event]
                      ];
                  }
              }
          }
          // DNS options
          if ('family' in options) {
              deprecationWarning.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"');
          }
          // HTTPS options
          if (defaults === null || defaults === void 0 ? void 0 : defaults.https) {
              options.https = { ...defaults.https, ...options.https };
          }
          if ('rejectUnauthorized' in options) {
              deprecationWarning.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"');
          }
          if ('checkServerIdentity' in options) {
              deprecationWarning.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"');
          }
          if ('ca' in options) {
              deprecationWarning.default('"options.ca" was never documented, please use "options.https.certificateAuthority"');
          }
          if ('key' in options) {
              deprecationWarning.default('"options.key" was never documented, please use "options.https.key"');
          }
          if ('cert' in options) {
              deprecationWarning.default('"options.cert" was never documented, please use "options.https.certificate"');
          }
          if ('passphrase' in options) {
              deprecationWarning.default('"options.passphrase" was never documented, please use "options.https.passphrase"');
          }
          if ('pfx' in options) {
              deprecationWarning.default('"options.pfx" was never documented, please use "options.https.pfx"');
          }
          // Other options
          if ('followRedirects' in options) {
              throw new TypeError('The `followRedirects` option does not exist. Use `followRedirect` instead.');
          }
          if (options.agent) {
              for (const key in options.agent) {
                  if (key !== 'http' && key !== 'https' && key !== 'http2') {
                      throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${key}\``);
                  }
              }
          }
          options.maxRedirects = (_e = options.maxRedirects) !== null && _e !== void 0 ? _e : 0;
          // Set non-enumerable properties
          exports.setNonEnumerableProperties([defaults, rawOptions], options);
          return normalizeArguments_1.default(options, defaults);
      }
      _lockWrite() {
          const onLockedWrite = () => {
              throw new TypeError('The payload has been already provided');
          };
          this.write = onLockedWrite;
          this.end = onLockedWrite;
      }
      _unlockWrite() {
          this.write = super.write;
          this.end = super.end;
      }
      async _finalizeBody() {
          const { options } = this;
          const { headers } = options;
          const isForm = !dist.default.undefined(options.form);
          const isJSON = !dist.default.undefined(options.json);
          const isBody = !dist.default.undefined(options.body);
          const hasPayload = isForm || isJSON || isBody;
          const cannotHaveBody = exports.withoutBody.has(options.method) && !(options.method === 'GET' && options.allowGetBody);
          this._cannotHaveBody = cannotHaveBody;
          if (hasPayload) {
              if (cannotHaveBody) {
                  throw new TypeError(`The \`${options.method}\` method cannot be used with a body`);
              }
              if ([isBody, isForm, isJSON].filter(isTrue => isTrue).length > 1) {
                  throw new TypeError('The `body`, `json` and `form` options are mutually exclusive');
              }
              if (isBody &&
                  !(options.body instanceof Stream.Readable) &&
                  !dist.default.string(options.body) &&
                  !dist.default.buffer(options.body) &&
                  !isFormData.default(options.body)) {
                  throw new TypeError('The `body` option must be a stream.Readable, string or Buffer');
              }
              if (isForm && !dist.default.object(options.form)) {
                  throw new TypeError('The `form` option must be an Object');
              }
              {
                  // Serialize body
                  const noContentType = !dist.default.string(headers['content-type']);
                  if (isBody) {
                      // Special case for https://github.com/form-data/form-data
                      if (isFormData.default(options.body) && noContentType) {
                          headers['content-type'] = `multipart/form-data; boundary=${options.body.getBoundary()}`;
                      }
                      this[kBody] = options.body;
                  }
                  else if (isForm) {
                      if (noContentType) {
                          headers['content-type'] = 'application/x-www-form-urlencoded';
                      }
                      this[kBody] = (new Url.URLSearchParams(options.form)).toString();
                  }
                  else {
                      if (noContentType) {
                          headers['content-type'] = 'application/json';
                      }
                      this[kBody] = options.stringifyJson(options.json);
                  }
                  const uploadBodySize = await getBodySize.default(this[kBody], options.headers);
                  // See https://tools.ietf.org/html/rfc7230#section-3.3.2
                  // A user agent SHOULD send a Content-Length in a request message when
                  // no Transfer-Encoding is sent and the request method defines a meaning
                  // for an enclosed payload body.  For example, a Content-Length header
                  // field is normally sent in a POST request even when the value is 0
                  // (indicating an empty payload body).  A user agent SHOULD NOT send a
                  // Content-Length header field when the request message does not contain
                  // a payload body and the method semantics do not anticipate such a
                  // body.
                  if (dist.default.undefined(headers['content-length']) && dist.default.undefined(headers['transfer-encoding'])) {
                      if (!cannotHaveBody && !dist.default.undefined(uploadBodySize)) {
                          headers['content-length'] = String(uploadBodySize);
                      }
                  }
              }
          }
          else if (cannotHaveBody) {
              this._lockWrite();
          }
          else {
              this._unlockWrite();
          }
          this[kBodySize] = Number(headers['content-length']) || undefined;
      }
      async _onResponseBase(response) {
          const { options } = this;
          const { url } = options;
          this[kOriginalResponse] = response;
          if (options.decompress) {
              response = decompressResponse(response);
          }
          const statusCode = response.statusCode;
          const typedResponse = response;
          typedResponse.statusMessage = typedResponse.statusMessage ? typedResponse.statusMessage : http.STATUS_CODES[statusCode];
          typedResponse.url = options.url.toString();
          typedResponse.requestUrl = this.requestUrl;
          typedResponse.redirectUrls = this.redirects;
          typedResponse.request = this;
          typedResponse.isFromCache = response.fromCache || false;
          typedResponse.ip = this.ip;
          typedResponse.retryCount = this.retryCount;
          this[kIsFromCache] = typedResponse.isFromCache;
          this[kResponseSize] = Number(response.headers['content-length']) || undefined;
          this[kResponse] = response;
          response.once('end', () => {
              this[kResponseSize] = this[kDownloadedSize];
              this.emit('downloadProgress', this.downloadProgress);
          });
          response.once('error', (error) => {
              // Force clean-up, because some packages don't do this.
              // TODO: Fix decompress-response
              response.destroy();
              this._beforeError(new ReadError(error, this));
          });
          response.once('aborted', () => {
              this._beforeError(new ReadError({
                  name: 'Error',
                  message: 'The server aborted pending request',
                  code: 'ECONNRESET'
              }, this));
          });
          this.emit('downloadProgress', this.downloadProgress);
          const rawCookies = response.headers['set-cookie'];
          if (dist.default.object(options.cookieJar) && rawCookies) {
              let promises = rawCookies.map(async (rawCookie) => options.cookieJar.setCookie(rawCookie, url.toString()));
              if (options.ignoreInvalidCookies) {
                  promises = promises.map(async (p) => p.catch(() => { }));
              }
              try {
                  await Promise.all(promises);
              }
              catch (error) {
                  this._beforeError(error);
                  return;
              }
          }
          if (options.followRedirect && response.headers.location && redirectCodes.has(statusCode)) {
              // We're being redirected, we don't care about the response.
              // It'd be best to abort the request, but we can't because
              // we would have to sacrifice the TCP connection. We don't want that.
              response.resume();
              if (this[kRequest]) {
                  this[kCancelTimeouts]();
                  // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
                  delete this[kRequest];
                  this[kUnproxyEvents]();
              }
              const shouldBeGet = statusCode === 303 && options.method !== 'GET' && options.method !== 'HEAD';
              if (shouldBeGet || !options.methodRewriting) {
                  // Server responded with "see other", indicating that the resource exists at another location,
                  // and the client should request it from that location via GET or HEAD.
                  options.method = 'GET';
                  if ('body' in options) {
                      delete options.body;
                  }
                  if ('json' in options) {
                      delete options.json;
                  }
                  if ('form' in options) {
                      delete options.form;
                  }
                  this[kBody] = undefined;
                  delete options.headers['content-length'];
              }
              if (this.redirects.length >= options.maxRedirects) {
                  this._beforeError(new MaxRedirectsError(this));
                  return;
              }
              try {
                  // Do not remove. See https://github.com/sindresorhus/got/pull/214
                  const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
                  // Handles invalid URLs. See https://github.com/sindresorhus/got/issues/604
                  const redirectUrl = new Url.URL(redirectBuffer, url);
                  const redirectString = redirectUrl.toString();
                  decodeURI(redirectString);
                  // Redirecting to a different site, clear sensitive data.
                  if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) {
                      if ('host' in options.headers) {
                          delete options.headers.host;
                      }
                      if ('cookie' in options.headers) {
                          delete options.headers.cookie;
                      }
                      if ('authorization' in options.headers) {
                          delete options.headers.authorization;
                      }
                      if (options.username || options.password) {
                          options.username = '';
                          options.password = '';
                      }
                  }
                  else {
                      redirectUrl.username = options.username;
                      redirectUrl.password = options.password;
                  }
                  this.redirects.push(redirectString);
                  options.url = redirectUrl;
                  for (const hook of options.hooks.beforeRedirect) {
                      // eslint-disable-next-line no-await-in-loop
                      await hook(options, typedResponse);
                  }
                  this.emit('redirect', typedResponse, options);
                  await this._makeRequest();
              }
              catch (error) {
                  this._beforeError(error);
                  return;
              }
              return;
          }
          if (options.isStream && options.throwHttpErrors && !isResponseOk.isResponseOk(typedResponse)) {
              this._beforeError(new HTTPError(typedResponse));
              return;
          }
          response.on('readable', () => {
              if (this[kTriggerRead]) {
                  this._read();
              }
          });
          this.on('resume', () => {
              response.resume();
          });
          this.on('pause', () => {
              response.pause();
          });
          response.once('end', () => {
              this.push(null);
          });
          this.emit('response', response);
          for (const destination of this[kServerResponsesPiped]) {
              if (destination.headersSent) {
                  continue;
              }
              // eslint-disable-next-line guard-for-in
              for (const key in response.headers) {
                  const isAllowed = options.decompress ? key !== 'content-encoding' : true;
                  const value = response.headers[key];
                  if (isAllowed) {
                      destination.setHeader(key, value);
                  }
              }
              destination.statusCode = statusCode;
          }
      }
      async _onResponse(response) {
          try {
              await this._onResponseBase(response);
          }
          catch (error) {
              /* istanbul ignore next: better safe than sorry */
              this._beforeError(error);
          }
      }
      _onRequest(request) {
          const { options } = this;
          const { timeout, url } = options;
          source$1.default(request);
          this[kCancelTimeouts] = timedOut.default(request, timeout, url);
          const responseEventName = options.cache ? 'cacheableResponse' : 'response';
          request.once(responseEventName, (response) => {
              void this._onResponse(response);
          });
          request.once('error', (error) => {
              var _a;
              // Force clean-up, because some packages (e.g. nock) don't do this.
              request.destroy();
              // Node.js <= 12.18.2 mistakenly emits the response `end` first.
              (_a = request.res) === null || _a === void 0 ? void 0 : _a.removeAllListeners('end');
              error = error instanceof timedOut.TimeoutError ? new TimeoutError(error, this.timings, this) : new RequestError(error.message, error, this);
              this._beforeError(error);
          });
          this[kUnproxyEvents] = proxyEvents$1.default(request, this, proxiedRequestEvents);
          this[kRequest] = request;
          this.emit('uploadProgress', this.uploadProgress);
          // Send body
          const body = this[kBody];
          const currentRequest = this.redirects.length === 0 ? this : request;
          if (dist.default.nodeStream(body)) {
              body.pipe(currentRequest);
              body.once('error', (error) => {
                  this._beforeError(new UploadError(error, this));
              });
          }
          else {
              this._unlockWrite();
              if (!dist.default.undefined(body)) {
                  this._writeRequest(body, undefined, () => { });
                  currentRequest.end();
                  this._lockWrite();
              }
              else if (this._cannotHaveBody || this._noPipe) {
                  currentRequest.end();
                  this._lockWrite();
              }
          }
          this.emit('request', request);
      }
      async _createCacheableRequest(url, options) {
          return new Promise((resolve, reject) => {
              // TODO: Remove `utils/url-to-options.ts` when `cacheable-request` is fixed
              Object.assign(options, urlToOptions$1.default(url));
              // `http-cache-semantics` checks this
              // TODO: Fix this ignore.
              // @ts-expect-error
              delete options.url;
              let request;
              // This is ugly
              const cacheRequest = cacheableStore.get(options.cache)(options, async (response) => {
                  // TODO: Fix `cacheable-response`
                  response._readableState.autoDestroy = false;
                  if (request) {
                      (await request).emit('cacheableResponse', response);
                  }
                  resolve(response);
              });
              // Restore options
              options.url = url;
              cacheRequest.once('error', reject);
              cacheRequest.once('request', async (requestOrPromise) => {
                  request = requestOrPromise;
                  resolve(request);
              });
          });
      }
      async _makeRequest() {
          var _a, _b, _c, _d, _e;
          const { options } = this;
          const { headers } = options;
          for (const key in headers) {
              if (dist.default.undefined(headers[key])) {
                  // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
                  delete headers[key];
              }
              else if (dist.default.null_(headers[key])) {
                  throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${key}\` header`);
              }
          }
          if (options.decompress && dist.default.undefined(headers['accept-encoding'])) {
              headers['accept-encoding'] = supportsBrotli ? 'gzip, deflate, br' : 'gzip, deflate';
          }
          // Set cookies
          if (options.cookieJar) {
              const cookieString = await options.cookieJar.getCookieString(options.url.toString());
              if (dist.default.nonEmptyString(cookieString)) {
                  options.headers.cookie = cookieString;
              }
          }
          for (const hook of options.hooks.beforeRequest) {
              // eslint-disable-next-line no-await-in-loop
              const result = await hook(options);
              if (!dist.default.undefined(result)) {
                  // @ts-expect-error Skip the type mismatch to support abstract responses
                  options.request = () => result;
                  break;
              }
          }
          if (options.body && this[kBody] !== options.body) {
              this[kBody] = options.body;
          }
          const { agent, request, timeout, url } = options;
          if (options.dnsCache && !('lookup' in options)) {
              options.lookup = options.dnsCache.lookup;
          }
          // UNIX sockets
          if (url.hostname === 'unix') {
              const matches = /(?<socketPath>.+?):(?<path>.+)/.exec(`${url.pathname}${url.search}`);
              if (matches === null || matches === void 0 ? void 0 : matches.groups) {
                  const { socketPath, path } = matches.groups;
                  Object.assign(options, {
                      socketPath,
                      path,
                      host: ''
                  });
              }
          }
          const isHttps = url.protocol === 'https:';
          // Fallback function
          let fallbackFn;
          if (options.http2) {
              fallbackFn = source$3.auto;
          }
          else {
              fallbackFn = isHttps ? https.request : http.request;
          }
          const realFn = (_a = options.request) !== null && _a !== void 0 ? _a : fallbackFn;
          // Cache support
          const fn = options.cache ? this._createCacheableRequest : realFn;
          // Pass an agent directly when HTTP2 is disabled
          if (agent && !options.http2) {
              options.agent = agent[isHttps ? 'https' : 'http'];
          }
          // Prepare plain HTTP request options
          options[kRequest] = realFn;
          delete options.request;
          // TODO: Fix this ignore.
          // @ts-expect-error
          delete options.timeout;
          const requestOptions = options;
          requestOptions.shared = (_b = options.cacheOptions) === null || _b === void 0 ? void 0 : _b.shared;
          requestOptions.cacheHeuristic = (_c = options.cacheOptions) === null || _c === void 0 ? void 0 : _c.cacheHeuristic;
          requestOptions.immutableMinTimeToLive = (_d = options.cacheOptions) === null || _d === void 0 ? void 0 : _d.immutableMinTimeToLive;
          requestOptions.ignoreCargoCult = (_e = options.cacheOptions) === null || _e === void 0 ? void 0 : _e.ignoreCargoCult;
          // If `dnsLookupIpVersion` is not present do not override `family`
          if (options.dnsLookupIpVersion !== undefined) {
              try {
                  requestOptions.family = dnsIpVersion.dnsLookupIpVersionToFamily(options.dnsLookupIpVersion);
              }
              catch (_f) {
                  throw new Error('Invalid `dnsLookupIpVersion` option value');
              }
          }
          // HTTPS options remapping
          if (options.https) {
              if ('rejectUnauthorized' in options.https) {
                  requestOptions.rejectUnauthorized = options.https.rejectUnauthorized;
              }
              if (options.https.checkServerIdentity) {
                  requestOptions.checkServerIdentity = options.https.checkServerIdentity;
              }
              if (options.https.certificateAuthority) {
                  requestOptions.ca = options.https.certificateAuthority;
              }
              if (options.https.certificate) {
                  requestOptions.cert = options.https.certificate;
              }
              if (options.https.key) {
                  requestOptions.key = options.https.key;
              }
              if (options.https.passphrase) {
                  requestOptions.passphrase = options.https.passphrase;
              }
              if (options.https.pfx) {
                  requestOptions.pfx = options.https.pfx;
              }
          }
          try {
              let requestOrResponse = await fn(url, requestOptions);
              if (dist.default.undefined(requestOrResponse)) {
                  requestOrResponse = fallbackFn(url, requestOptions);
              }
              // Restore options
              options.request = request;
              options.timeout = timeout;
              options.agent = agent;
              // HTTPS options restore
              if (options.https) {
                  if ('rejectUnauthorized' in options.https) {
                      delete requestOptions.rejectUnauthorized;
                  }
                  if (options.https.checkServerIdentity) {
                      // @ts-expect-error - This one will be removed when we remove the alias.
                      delete requestOptions.checkServerIdentity;
                  }
                  if (options.https.certificateAuthority) {
                      delete requestOptions.ca;
                  }
                  if (options.https.certificate) {
                      delete requestOptions.cert;
                  }
                  if (options.https.key) {
                      delete requestOptions.key;
                  }
                  if (options.https.passphrase) {
                      delete requestOptions.passphrase;
                  }
                  if (options.https.pfx) {
                      delete requestOptions.pfx;
                  }
              }
              if (isClientRequest(requestOrResponse)) {
                  this._onRequest(requestOrResponse);
                  // Emit the response after the stream has been ended
              }
              else if (this.writable) {
                  this.once('finish', () => {
                      void this._onResponse(requestOrResponse);
                  });
                  this._unlockWrite();
                  this.end();
                  this._lockWrite();
              }
              else {
                  void this._onResponse(requestOrResponse);
              }
          }
          catch (error) {
              if (error instanceof src$3.CacheError) {
                  throw new CacheError(error, this);
              }
              throw new RequestError(error.message, error, this);
          }
      }
      async _error(error) {
          try {
              for (const hook of this.options.hooks.beforeError) {
                  // eslint-disable-next-line no-await-in-loop
                  error = await hook(error);
              }
          }
          catch (error_) {
              error = new RequestError(error_.message, error_, this);
          }
          this.destroy(error);
      }
      _beforeError(error) {
          if (this[kStopReading]) {
              return;
          }
          const { options } = this;
          const retryCount = this.retryCount + 1;
          this[kStopReading] = true;
          if (!(error instanceof RequestError)) {
              error = new RequestError(error.message, error, this);
          }
          const typedError = error;
          const { response } = typedError;
          void (async () => {
              if (response && !response.body) {
                  response.setEncoding(this._readableState.encoding);
                  try {
                      response.rawBody = await getBuffer_1.default(response);
                      response.body = response.rawBody.toString();
                  }
                  catch (_a) { }
              }
              if (this.listenerCount('retry') !== 0) {
                  let backoff;
                  try {
                      let retryAfter;
                      if (response && 'retry-after' in response.headers) {
                          retryAfter = Number(response.headers['retry-after']);
                          if (Number.isNaN(retryAfter)) {
                              retryAfter = Date.parse(response.headers['retry-after']) - Date.now();
                              if (retryAfter <= 0) {
                                  retryAfter = 1;
                              }
                          }
                          else {
                              retryAfter *= 1000;
                          }
                      }
                      backoff = await options.retry.calculateDelay({
                          attemptCount: retryCount,
                          retryOptions: options.retry,
                          error: typedError,
                          retryAfter,
                          computedValue: calculateRetryDelay_1.default({
                              attemptCount: retryCount,
                              retryOptions: options.retry,
                              error: typedError,
                              retryAfter,
                              computedValue: 0
                          })
                      });
                  }
                  catch (error_) {
                      void this._error(new RequestError(error_.message, error_, this));
                      return;
                  }
                  if (backoff) {
                      const retry = async () => {
                          try {
                              for (const hook of this.options.hooks.beforeRetry) {
                                  // eslint-disable-next-line no-await-in-loop
                                  await hook(this.options, typedError, retryCount);
                              }
                          }
                          catch (error_) {
                              void this._error(new RequestError(error_.message, error, this));
                              return;
                          }
                          // Something forced us to abort the retry
                          if (this.destroyed) {
                              return;
                          }
                          this.destroy();
                          this.emit('retry', retryCount, error);
                      };
                      this[kRetryTimeout] = setTimeout(retry, backoff);
                      return;
                  }
              }
              void this._error(typedError);
          })();
      }
      _read() {
          this[kTriggerRead] = true;
          const response = this[kResponse];
          if (response && !this[kStopReading]) {
              // We cannot put this in the `if` above
              // because `.read()` also triggers the `end` event
              if (response.readableLength) {
                  this[kTriggerRead] = false;
              }
              let data;
              while ((data = response.read()) !== null) {
                  this[kDownloadedSize] += data.length;
                  this[kStartedReading] = true;
                  const progress = this.downloadProgress;
                  if (progress.percent < 1) {
                      this.emit('downloadProgress', progress);
                  }
                  this.push(data);
              }
          }
      }
      // Node.js 12 has incorrect types, so the encoding must be a string
      _write(chunk, encoding, callback) {
          const write = () => {
              this._writeRequest(chunk, encoding, callback);
          };
          if (this.requestInitialized) {
              write();
          }
          else {
              this[kJobs].push(write);
          }
      }
      _writeRequest(chunk, encoding, callback) {
          if (this[kRequest].destroyed) {
              // Probably the `ClientRequest` instance will throw
              return;
          }
          this._progressCallbacks.push(() => {
              this[kUploadedSize] += Buffer.byteLength(chunk, encoding);
              const progress = this.uploadProgress;
              if (progress.percent < 1) {
                  this.emit('uploadProgress', progress);
              }
          });
          // TODO: What happens if it's from cache? Then this[kRequest] won't be defined.
          this[kRequest].write(chunk, encoding, (error) => {
              if (!error && this._progressCallbacks.length > 0) {
                  this._progressCallbacks.shift()();
              }
              callback(error);
          });
      }
      _final(callback) {
          const endRequest = () => {
              // FIX: Node.js 10 calls the write callback AFTER the end callback!
              while (this._progressCallbacks.length !== 0) {
                  this._progressCallbacks.shift()();
              }
              // We need to check if `this[kRequest]` is present,
              // because it isn't when we use cache.
              if (!(kRequest in this)) {
                  callback();
                  return;
              }
              if (this[kRequest].destroyed) {
                  callback();
                  return;
              }
              this[kRequest].end((error) => {
                  if (!error) {
                      this[kBodySize] = this[kUploadedSize];
                      this.emit('uploadProgress', this.uploadProgress);
                      this[kRequest].emit('upload-complete');
                  }
                  callback(error);
              });
          };
          if (this.requestInitialized) {
              endRequest();
          }
          else {
              this[kJobs].push(endRequest);
          }
      }
      _destroy(error, callback) {
          var _a;
          this[kStopReading] = true;
          // Prevent further retries
          clearTimeout(this[kRetryTimeout]);
          if (kRequest in this) {
              this[kCancelTimeouts]();
              // TODO: Remove the next `if` when these get fixed:
              // - https://github.com/nodejs/node/issues/32851
              if (!((_a = this[kResponse]) === null || _a === void 0 ? void 0 : _a.complete)) {
                  this[kRequest].destroy();
              }
          }
          if (error !== null && !dist.default.undefined(error) && !(error instanceof RequestError)) {
              error = new RequestError(error.message, error, this);
          }
          callback(error);
      }
      get _isAboutToError() {
          return this[kStopReading];
      }
      /**
      The remote IP address.
      */
      get ip() {
          var _a;
          return (_a = this.socket) === null || _a === void 0 ? void 0 : _a.remoteAddress;
      }
      /**
      Indicates whether the request has been aborted or not.
      */
      get aborted() {
          var _a, _b, _c;
          return ((_b = (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.destroyed) !== null && _b !== void 0 ? _b : this.destroyed) && !((_c = this[kOriginalResponse]) === null || _c === void 0 ? void 0 : _c.complete);
      }
      get socket() {
          var _a, _b;
          return (_b = (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.socket) !== null && _b !== void 0 ? _b : undefined;
      }
      /**
      Progress event for downloading (receiving a response).
      */
      get downloadProgress() {
          let percent;
          if (this[kResponseSize]) {
              percent = this[kDownloadedSize] / this[kResponseSize];
          }
          else if (this[kResponseSize] === this[kDownloadedSize]) {
              percent = 1;
          }
          else {
              percent = 0;
          }
          return {
              percent,
              transferred: this[kDownloadedSize],
              total: this[kResponseSize]
          };
      }
      /**
      Progress event for uploading (sending a request).
      */
      get uploadProgress() {
          let percent;
          if (this[kBodySize]) {
              percent = this[kUploadedSize] / this[kBodySize];
          }
          else if (this[kBodySize] === this[kUploadedSize]) {
              percent = 1;
          }
          else {
              percent = 0;
          }
          return {
              percent,
              transferred: this[kUploadedSize],
              total: this[kBodySize]
          };
      }
      /**
      The object contains the following properties:
  
      - `start` - Time when the request started.
      - `socket` - Time when a socket was assigned to the request.
      - `lookup` - Time when the DNS lookup finished.
      - `connect` - Time when the socket successfully connected.
      - `secureConnect` - Time when the socket securely connected.
      - `upload` - Time when the request finished uploading.
      - `response` - Time when the request fired `response` event.
      - `end` - Time when the response fired `end` event.
      - `error` - Time when the request fired `error` event.
      - `abort` - Time when the request fired `abort` event.
      - `phases`
          - `wait` - `timings.socket - timings.start`
          - `dns` - `timings.lookup - timings.socket`
          - `tcp` - `timings.connect - timings.lookup`
          - `tls` - `timings.secureConnect - timings.connect`
          - `request` - `timings.upload - (timings.secureConnect || timings.connect)`
          - `firstByte` - `timings.response - timings.upload`
          - `download` - `timings.end - timings.response`
          - `total` - `(timings.end || timings.error || timings.abort) - timings.start`
  
      If something has not been measured yet, it will be `undefined`.
  
      __Note__: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
      */
      get timings() {
          var _a;
          return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.timings;
      }
      /**
      Whether the response was retrieved from the cache.
      */
      get isFromCache() {
          return this[kIsFromCache];
      }
      pipe(destination, options) {
          if (this[kStartedReading]) {
              throw new Error('Failed to pipe. The response has been emitted already.');
          }
          if (destination instanceof http_1.ServerResponse) {
              this[kServerResponsesPiped].add(destination);
          }
          return super.pipe(destination, options);
      }
      unpipe(destination) {
          if (destination instanceof http_1.ServerResponse) {
              this[kServerResponsesPiped].delete(destination);
          }
          super.unpipe(destination);
          return this;
      }
  }
  exports.default = Request;
  });
  
  var types = createCommonjsModule(function (module, exports) {
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.CancelError = exports.ParseError = void 0;
  
  /**
  An error to be thrown when server response code is 2xx, and parsing body fails.
  Includes a `response` property.
  */
  class ParseError extends core$2.RequestError {
      constructor(error, response) {
          const { options } = response.request;
          super(`${error.message} in "${options.url.toString()}"`, error, response.request);
          this.name = 'ParseError';
      }
  }
  exports.ParseError = ParseError;
  /**
  An error to be thrown when the request is aborted with `.cancel()`.
  */
  class CancelError extends core$2.RequestError {
      constructor(request) {
          super('Promise was canceled', {}, request);
          this.name = 'CancelError';
      }
      get isCanceled() {
          return true;
      }
  }
  exports.CancelError = CancelError;
  __exportStar(core$2, exports);
  });
  
  var parseBody_1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  const parseBody = (response, responseType, parseJson, encoding) => {
      const { rawBody } = response;
      try {
          if (responseType === 'text') {
              return rawBody.toString(encoding);
          }
          if (responseType === 'json') {
              return rawBody.length === 0 ? '' : parseJson(rawBody.toString());
          }
          if (responseType === 'buffer') {
              return rawBody;
          }
          throw new types.ParseError({
              message: `Unknown body type '${responseType}'`,
              name: 'Error'
          }, response);
      }
      catch (error) {
          throw new types.ParseError(error, response);
      }
  };
  exports.default = parseBody;
  });
  
  var asPromise_1 = createCommonjsModule(function (module, exports) {
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  
  
  
  
  
  
  
  
  
  const proxiedRequestEvents = [
      'request',
      'response',
      'redirect',
      'uploadProgress',
      'downloadProgress'
  ];
  function asPromise(normalizedOptions) {
      let globalRequest;
      let globalResponse;
      const emitter = new events.EventEmitter();
      const promise = new pCancelable((resolve, reject, onCancel) => {
          const makeRequest = (retryCount) => {
              const request = new core$2.default(undefined, normalizedOptions);
              request.retryCount = retryCount;
              request._noPipe = true;
              onCancel(() => request.destroy());
              onCancel.shouldReject = false;
              onCancel(() => reject(new types.CancelError(request)));
              globalRequest = request;
              request.once('response', async (response) => {
                  var _a;
                  response.retryCount = retryCount;
                  if (response.request.aborted) {
                      // Canceled while downloading - will throw a `CancelError` or `TimeoutError` error
                      return;
                  }
                  // Download body
                  let rawBody;
                  try {
                      rawBody = await getBuffer_1.default(request);
                      response.rawBody = rawBody;
                  }
                  catch (_b) {
                      // The same error is caught below.
                      // See request.once('error')
                      return;
                  }
                  if (request._isAboutToError) {
                      return;
                  }
                  // Parse body
                  const contentEncoding = ((_a = response.headers['content-encoding']) !== null && _a !== void 0 ? _a : '').toLowerCase();
                  const isCompressed = ['gzip', 'deflate', 'br'].includes(contentEncoding);
                  const { options } = request;
                  if (isCompressed && !options.decompress) {
                      response.body = rawBody;
                  }
                  else {
                      try {
                          response.body = parseBody_1.default(response, options.responseType, options.parseJson, options.encoding);
                      }
                      catch (error) {
                          // Fallback to `utf8`
                          response.body = rawBody.toString();
                          if (isResponseOk.isResponseOk(response)) {
                              request._beforeError(error);
                              return;
                          }
                      }
                  }
                  try {
                      for (const [index, hook] of options.hooks.afterResponse.entries()) {
                          // @ts-expect-error TS doesn't notice that CancelableRequest is a Promise
                          // eslint-disable-next-line no-await-in-loop
                          response = await hook(response, async (updatedOptions) => {
                              const typedOptions = core$2.default.normalizeArguments(undefined, {
                                  ...updatedOptions,
                                  retry: {
                                      calculateDelay: () => 0
                                  },
                                  throwHttpErrors: false,
                                  resolveBodyOnly: false
                              }, options);
                              // Remove any further hooks for that request, because we'll call them anyway.
                              // The loop continues. We don't want duplicates (asPromise recursion).
                              typedOptions.hooks.afterResponse = typedOptions.hooks.afterResponse.slice(0, index);
                              for (const hook of typedOptions.hooks.beforeRetry) {
                                  // eslint-disable-next-line no-await-in-loop
                                  await hook(typedOptions);
                              }
                              const promise = asPromise(typedOptions);
                              onCancel(() => {
                                  promise.catch(() => { });
                                  promise.cancel();
                              });
                              return promise;
                          });
                      }
                  }
                  catch (error) {
                      request._beforeError(new types.RequestError(error.message, error, request));
                      return;
                  }
                  if (!isResponseOk.isResponseOk(response)) {
                      request._beforeError(new types.HTTPError(response));
                      return;
                  }
                  globalResponse = response;
                  resolve(request.options.resolveBodyOnly ? response.body : response);
              });
              const onError = (error) => {
                  if (promise.isCanceled) {
                      return;
                  }
                  const { options } = request;
                  if (error instanceof types.HTTPError && !options.throwHttpErrors) {
                      const { response } = error;
                      resolve(request.options.resolveBodyOnly ? response.body : response);
                      return;
                  }
                  reject(error);
              };
              request.once('error', onError);
              const previousBody = request.options.body;
              request.once('retry', (newRetryCount, error) => {
                  var _a, _b;
                  if (previousBody === ((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.body) && dist.default.nodeStream((_b = error.request) === null || _b === void 0 ? void 0 : _b.options.body)) {
                      onError(error);
                      return;
                  }
                  makeRequest(newRetryCount);
              });
              proxyEvents$1.default(request, emitter, proxiedRequestEvents);
          };
          makeRequest(0);
      });
      promise.on = (event, fn) => {
          emitter.on(event, fn);
          return promise;
      };
      const shortcut = (responseType) => {
          const newPromise = (async () => {
              // Wait until downloading has ended
              await promise;
              const { options } = globalResponse.request;
              return parseBody_1.default(globalResponse, responseType, options.parseJson, options.encoding);
          })();
          Object.defineProperties(newPromise, Object.getOwnPropertyDescriptors(promise));
          return newPromise;
      };
      promise.json = () => {
          const { headers } = globalRequest.options;
          if (!globalRequest.writableFinished && headers.accept === undefined) {
              headers.accept = 'application/json';
          }
          return shortcut('json');
      };
      promise.buffer = () => shortcut('buffer');
      promise.text = () => shortcut('text');
      return promise;
  }
  exports.default = asPromise;
  __exportStar(types, exports);
  });
  
  var createRejection_1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  function createRejection(error, ...beforeErrorGroups) {
      const promise = (async () => {
          if (error instanceof types.RequestError) {
              try {
                  for (const hooks of beforeErrorGroups) {
                      if (hooks) {
                          for (const hook of hooks) {
                              // eslint-disable-next-line no-await-in-loop
                              error = await hook(error);
                          }
                      }
                  }
              }
              catch (error_) {
                  error = error_;
              }
          }
          throw error;
      })();
      const returnPromise = () => promise;
      promise.json = returnPromise;
      promise.text = returnPromise;
      promise.buffer = returnPromise;
      promise.on = returnPromise;
      return promise;
  }
  exports.default = createRejection;
  });
  
  var deepFreeze_1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  function deepFreeze(object) {
      for (const value of Object.values(object)) {
          if (dist.default.plainObject(value) || dist.default.array(value)) {
              deepFreeze(value);
          }
      }
      return Object.freeze(object);
  }
  exports.default = deepFreeze;
  });
  
  var types$1 = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  });
  
  var create_1 = createCommonjsModule(function (module, exports) {
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.defaultHandler = void 0;
  
  
  
  
  
  const errors = {
      RequestError: asPromise_1.RequestError,
      CacheError: asPromise_1.CacheError,
      ReadError: asPromise_1.ReadError,
      HTTPError: asPromise_1.HTTPError,
      MaxRedirectsError: asPromise_1.MaxRedirectsError,
      TimeoutError: asPromise_1.TimeoutError,
      ParseError: asPromise_1.ParseError,
      CancelError: asPromise_1.CancelError,
      UnsupportedProtocolError: asPromise_1.UnsupportedProtocolError,
      UploadError: asPromise_1.UploadError
  };
  // The `delay` package weighs 10KB (!)
  const delay = async (ms) => new Promise(resolve => {
      setTimeout(resolve, ms);
  });
  const { normalizeArguments } = core$2.default;
  const mergeOptions = (...sources) => {
      let mergedOptions;
      for (const source of sources) {
          mergedOptions = normalizeArguments(undefined, source, mergedOptions);
      }
      return mergedOptions;
  };
  const getPromiseOrStream = (options) => options.isStream ? new core$2.default(undefined, options) : asPromise_1.default(options);
  const isGotInstance = (value) => ('defaults' in value && 'options' in value.defaults);
  const aliases = [
      'get',
      'post',
      'put',
      'patch',
      'head',
      'delete'
  ];
  exports.defaultHandler = (options, next) => next(options);
  const callInitHooks = (hooks, options) => {
      if (hooks) {
          for (const hook of hooks) {
              hook(options);
          }
      }
  };
  const create = (defaults) => {
      // Proxy properties from next handlers
      defaults._rawHandlers = defaults.handlers;
      defaults.handlers = defaults.handlers.map(fn => ((options, next) => {
          // This will be assigned by assigning result
          let root;
          const result = fn(options, newOptions => {
              root = next(newOptions);
              return root;
          });
          if (result !== root && !options.isStream && root) {
              const typedResult = result;
              const { then: promiseThen, catch: promiseCatch, finally: promiseFianlly } = typedResult;
              Object.setPrototypeOf(typedResult, Object.getPrototypeOf(root));
              Object.defineProperties(typedResult, Object.getOwnPropertyDescriptors(root));
              // These should point to the new promise
              // eslint-disable-next-line promise/prefer-await-to-then
              typedResult.then = promiseThen;
              typedResult.catch = promiseCatch;
              typedResult.finally = promiseFianlly;
          }
          return result;
      }));
      // Got interface
      const got = ((url, options = {}, _defaults) => {
          var _a, _b;
          let iteration = 0;
          const iterateHandlers = (newOptions) => {
              return defaults.handlers[iteration++](newOptions, iteration === defaults.handlers.length ? getPromiseOrStream : iterateHandlers);
          };
          // TODO: Remove this in Got 12.
          if (dist.default.plainObject(url)) {
              const mergedOptions = {
                  ...url,
                  ...options
              };
              core$2.setNonEnumerableProperties([url, options], mergedOptions);
              options = mergedOptions;
              url = undefined;
          }
          try {
              // Call `init` hooks
              let initHookError;
              try {
                  callInitHooks(defaults.options.hooks.init, options);
                  callInitHooks((_a = options.hooks) === null || _a === void 0 ? void 0 : _a.init, options);
              }
              catch (error) {
                  initHookError = error;
              }
              // Normalize options & call handlers
              const normalizedOptions = normalizeArguments(url, options, _defaults !== null && _defaults !== void 0 ? _defaults : defaults.options);
              normalizedOptions[core$2.kIsNormalizedAlready] = true;
              if (initHookError) {
                  throw new asPromise_1.RequestError(initHookError.message, initHookError, normalizedOptions);
              }
              return iterateHandlers(normalizedOptions);
          }
          catch (error) {
              if (options.isStream) {
                  throw error;
              }
              else {
                  return createRejection_1.default(error, defaults.options.hooks.beforeError, (_b = options.hooks) === null || _b === void 0 ? void 0 : _b.beforeError);
              }
          }
      });
      got.extend = (...instancesOrOptions) => {
          const optionsArray = [defaults.options];
          let handlers = [...defaults._rawHandlers];
          let isMutableDefaults;
          for (const value of instancesOrOptions) {
              if (isGotInstance(value)) {
                  optionsArray.push(value.defaults.options);
                  handlers.push(...value.defaults._rawHandlers);
                  isMutableDefaults = value.defaults.mutableDefaults;
              }
              else {
                  optionsArray.push(value);
                  if ('handlers' in value) {
                      handlers.push(...value.handlers);
                  }
                  isMutableDefaults = value.mutableDefaults;
              }
          }
          handlers = handlers.filter(handler => handler !== exports.defaultHandler);
          if (handlers.length === 0) {
              handlers.push(exports.defaultHandler);
          }
          return create({
              options: mergeOptions(...optionsArray),
              handlers,
              mutableDefaults: Boolean(isMutableDefaults)
          });
      };
      // Pagination
      const paginateEach = (async function* (url, options) {
          // TODO: Remove this `@ts-expect-error` when upgrading to TypeScript 4.
          // Error: Argument of type 'Merge<Options, PaginationOptions<T, R>> | undefined' is not assignable to parameter of type 'Options | undefined'.
          // @ts-expect-error
          let normalizedOptions = normalizeArguments(url, options, defaults.options);
          normalizedOptions.resolveBodyOnly = false;
          const pagination = normalizedOptions.pagination;
          if (!dist.default.object(pagination)) {
              throw new TypeError('`options.pagination` must be implemented');
          }
          const all = [];
          let { countLimit } = pagination;
          let numberOfRequests = 0;
          while (numberOfRequests < pagination.requestLimit) {
              if (numberOfRequests !== 0) {
                  // eslint-disable-next-line no-await-in-loop
                  await delay(pagination.backoff);
              }
              // @ts-expect-error FIXME!
              // TODO: Throw when result is not an instance of Response
              // eslint-disable-next-line no-await-in-loop
              const result = (await got(undefined, undefined, normalizedOptions));
              // eslint-disable-next-line no-await-in-loop
              const parsed = await pagination.transform(result);
              const current = [];
              for (const item of parsed) {
                  if (pagination.filter(item, all, current)) {
                      if (!pagination.shouldContinue(item, all, current)) {
                          return;
                      }
                      yield item;
                      if (pagination.stackAllItems) {
                          all.push(item);
                      }
                      current.push(item);
                      if (--countLimit <= 0) {
                          return;
                      }
                  }
              }
              const optionsToMerge = pagination.paginate(result, all, current);
              if (optionsToMerge === false) {
                  return;
              }
              if (optionsToMerge === result.request.options) {
                  normalizedOptions = result.request.options;
              }
              else if (optionsToMerge !== undefined) {
                  normalizedOptions = normalizeArguments(undefined, optionsToMerge, normalizedOptions);
              }
              numberOfRequests++;
          }
      });
      got.paginate = paginateEach;
      got.paginate.all = (async (url, options) => {
          const results = [];
          for await (const item of paginateEach(url, options)) {
              results.push(item);
          }
          return results;
      });
      // For those who like very descriptive names
      got.paginate.each = paginateEach;
      // Stream API
      got.stream = ((url, options) => got(url, { ...options, isStream: true }));
      // Shortcuts
      for (const method of aliases) {
          got[method] = ((url, options) => got(url, { ...options, method }));
          got.stream[method] = ((url, options) => {
              return got(url, { ...options, method, isStream: true });
          });
      }
      Object.assign(got, errors);
      Object.defineProperty(got, 'defaults', {
          value: defaults.mutableDefaults ? defaults : deepFreeze_1.default(defaults),
          writable: defaults.mutableDefaults,
          configurable: defaults.mutableDefaults,
          enumerable: true
      });
      got.mergeOptions = mergeOptions;
      return got;
  };
  exports.default = create;
  __exportStar(types$1, exports);
  });
  
  var source$4 = createCommonjsModule(function (module, exports) {
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  
  
  const defaults = {
      options: {
          method: 'GET',
          retry: {
              limit: 2,
              methods: [
                  'GET',
                  'PUT',
                  'HEAD',
                  'DELETE',
                  'OPTIONS',
                  'TRACE'
              ],
              statusCodes: [
                  408,
                  413,
                  429,
                  500,
                  502,
                  503,
                  504,
                  521,
                  522,
                  524
              ],
              errorCodes: [
                  'ETIMEDOUT',
                  'ECONNRESET',
                  'EADDRINUSE',
                  'ECONNREFUSED',
                  'EPIPE',
                  'ENOTFOUND',
                  'ENETUNREACH',
                  'EAI_AGAIN'
              ],
              maxRetryAfter: undefined,
              calculateDelay: ({ computedValue }) => computedValue
          },
          timeout: {},
          headers: {
              'user-agent': 'got (https://github.com/sindresorhus/got)'
          },
          hooks: {
              init: [],
              beforeRequest: [],
              beforeRedirect: [],
              beforeRetry: [],
              beforeError: [],
              afterResponse: []
          },
          cache: undefined,
          dnsCache: undefined,
          decompress: true,
          throwHttpErrors: true,
          followRedirect: true,
          isStream: false,
          responseType: 'text',
          resolveBodyOnly: false,
          maxRedirects: 10,
          prefixUrl: '',
          methodRewriting: true,
          ignoreInvalidCookies: false,
          context: {},
          // TODO: Set this to `true` when Got 12 gets released
          http2: false,
          allowGetBody: false,
          https: undefined,
          pagination: {
              transform: (response) => {
                  if (response.request.options.responseType === 'json') {
                      return response.body;
                  }
                  return JSON.parse(response.body);
              },
              paginate: response => {
                  if (!Reflect.has(response.headers, 'link')) {
                      return false;
                  }
                  const items = response.headers.link.split(',');
                  let next;
                  for (const item of items) {
                      const parsed = item.split(';');
                      if (parsed[1].includes('next')) {
                          next = parsed[0].trimStart().trim();
                          next = next.slice(1, -1);
                          break;
                      }
                  }
                  if (next) {
                      const options = {
                          url: new Url.URL(next)
                      };
                      return options;
                  }
                  return false;
              },
              filter: () => true,
              shouldContinue: () => true,
              countLimit: Infinity,
              backoff: 0,
              requestLimit: 10000,
              stackAllItems: true
          },
          parseJson: (text) => JSON.parse(text),
          stringifyJson: (object) => JSON.stringify(object),
          cacheOptions: {}
      },
      handlers: [create_1.defaultHandler],
      mutableDefaults: false
  };
  const got = create_1.default(defaults);
  exports.default = got;
  // For CommonJS default export support
  module.exports = got;
  module.exports.default = got;
  module.exports.__esModule = true; // Workaround for TS issue: https://github.com/sindresorhus/got/pull/1267
  __exportStar(create_1, exports);
  __exportStar(asPromise_1, exports);
  });
  
  var got = /*@__PURE__*/unwrapExports(source$4);
  
  var context = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Context = void 0;
  
  
  class Context {
      /**
       * Hydrate the context from the environment
       */
      constructor() {
          this.payload = {};
          if (process.env.GITHUB_EVENT_PATH) {
              if (fs.existsSync(process.env.GITHUB_EVENT_PATH)) {
                  this.payload = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' }));
              }
              else {
                  const path = process.env.GITHUB_EVENT_PATH;
                  process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os.EOL}`);
              }
          }
          this.eventName = process.env.GITHUB_EVENT_NAME;
          this.sha = process.env.GITHUB_SHA;
          this.ref = process.env.GITHUB_REF;
          this.workflow = process.env.GITHUB_WORKFLOW;
          this.action = process.env.GITHUB_ACTION;
          this.actor = process.env.GITHUB_ACTOR;
          this.job = process.env.GITHUB_JOB;
          this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10);
          this.runId = parseInt(process.env.GITHUB_RUN_ID, 10);
      }
      get issue() {
          const payload = this.payload;
          return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number });
      }
      get repo() {
          if (process.env.GITHUB_REPOSITORY) {
              const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
              return { owner, repo };
          }
          if (this.payload.repository) {
              return {
                  owner: this.payload.repository.owner.login,
                  repo: this.payload.repository.name
              };
          }
          throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'");
      }
  }
  exports.Context = Context;
  
  });
  
  var proxy = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  function getProxyUrl(reqUrl) {
      let usingSsl = reqUrl.protocol === 'https:';
      let proxyUrl;
      if (checkBypass(reqUrl)) {
          return proxyUrl;
      }
      let proxyVar;
      if (usingSsl) {
          proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];
      }
      else {
          proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];
      }
      if (proxyVar) {
          proxyUrl = new URL(proxyVar);
      }
      return proxyUrl;
  }
  exports.getProxyUrl = getProxyUrl;
  function checkBypass(reqUrl) {
      if (!reqUrl.hostname) {
          return false;
      }
      let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
      if (!noProxy) {
          return false;
      }
      // Determine the request port
      let reqPort;
      if (reqUrl.port) {
          reqPort = Number(reqUrl.port);
      }
      else if (reqUrl.protocol === 'http:') {
          reqPort = 80;
      }
      else if (reqUrl.protocol === 'https:') {
          reqPort = 443;
      }
      // Format the request hostname and hostname with port
      let upperReqHosts = [reqUrl.hostname.toUpperCase()];
      if (typeof reqPort === 'number') {
          upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
      }
      // Compare request host against noproxy
      for (let upperNoProxyItem of noProxy
          .split(',')
          .map(x => x.trim().toUpperCase())
          .filter(x => x)) {
          if (upperReqHosts.some(x => x === upperNoProxyItem)) {
              return true;
          }
      }
      return false;
  }
  exports.checkBypass = checkBypass;
  });
  
  var httpOverHttp_1 = httpOverHttp;
  var httpsOverHttp_1 = httpsOverHttp;
  var httpOverHttps_1 = httpOverHttps;
  var httpsOverHttps_1 = httpsOverHttps;
  
  
  function httpOverHttp(options) {
    var agent = new TunnelingAgent(options);
    agent.request = http.request;
    return agent;
  }
  
  function httpsOverHttp(options) {
    var agent = new TunnelingAgent(options);
    agent.request = http.request;
    agent.createSocket = createSecureSocket;
    agent.defaultPort = 443;
    return agent;
  }
  
  function httpOverHttps(options) {
    var agent = new TunnelingAgent(options);
    agent.request = https.request;
    return agent;
  }
  
  function httpsOverHttps(options) {
    var agent = new TunnelingAgent(options);
    agent.request = https.request;
    agent.createSocket = createSecureSocket;
    agent.defaultPort = 443;
    return agent;
  }
  
  
  function TunnelingAgent(options) {
    var self = this;
    self.options = options || {};
    self.proxyOptions = self.options.proxy || {};
    self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;
    self.requests = [];
    self.sockets = [];
  
    self.on('free', function onFree(socket, host, port, localAddress) {
      var options = toOptions(host, port, localAddress);
      for (var i = 0, len = self.requests.length; i < len; ++i) {
        var pending = self.requests[i];
        if (pending.host === options.host && pending.port === options.port) {
          // Detect the request to connect same origin server,
          // reuse the connection.
          self.requests.splice(i, 1);
          pending.request.onSocket(socket);
          return;
        }
      }
      socket.destroy();
      self.removeSocket(socket);
    });
  }
  util.inherits(TunnelingAgent, events.EventEmitter);
  
  TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {
    var self = this;
    var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));
  
    if (self.sockets.length >= this.maxSockets) {
      // We are over limit so we'll add it to the queue.
      self.requests.push(options);
      return;
    }
  
    // If we are under maxSockets create a new one.
    self.createSocket(options, function(socket) {
      socket.on('free', onFree);
      socket.on('close', onCloseOrRemove);
      socket.on('agentRemove', onCloseOrRemove);
      req.onSocket(socket);
  
      function onFree() {
        self.emit('free', socket, options);
      }
  
      function onCloseOrRemove(err) {
        self.removeSocket(socket);
        socket.removeListener('free', onFree);
        socket.removeListener('close', onCloseOrRemove);
        socket.removeListener('agentRemove', onCloseOrRemove);
      }
    });
  };
  
  TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
    var self = this;
    var placeholder = {};
    self.sockets.push(placeholder);
  
    var connectOptions = mergeOptions({}, self.proxyOptions, {
      method: 'CONNECT',
      path: options.host + ':' + options.port,
      agent: false,
      headers: {
        host: options.host + ':' + options.port
      }
    });
    if (options.localAddress) {
      connectOptions.localAddress = options.localAddress;
    }
    if (connectOptions.proxyAuth) {
      connectOptions.headers = connectOptions.headers || {};
      connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
          new Buffer(connectOptions.proxyAuth).toString('base64');
    }
  
    debug('making CONNECT request');
    var connectReq = self.request(connectOptions);
    connectReq.useChunkedEncodingByDefault = false; // for v0.6
    connectReq.once('response', onResponse); // for v0.6
    connectReq.once('upgrade', onUpgrade);   // for v0.6
    connectReq.once('connect', onConnect);   // for v0.7 or later
    connectReq.once('error', onError);
    connectReq.end();
  
    function onResponse(res) {
      // Very hacky. This is necessary to avoid http-parser leaks.
      res.upgrade = true;
    }
  
    function onUpgrade(res, socket, head) {
      // Hacky.
      process.nextTick(function() {
        onConnect(res, socket, head);
      });
    }
  
    function onConnect(res, socket, head) {
      connectReq.removeAllListeners();
      socket.removeAllListeners();
  
      if (res.statusCode !== 200) {
        debug('tunneling socket could not be established, statusCode=%d',
          res.statusCode);
        socket.destroy();
        var error = new Error('tunneling socket could not be established, ' +
          'statusCode=' + res.statusCode);
        error.code = 'ECONNRESET';
        options.request.emit('error', error);
        self.removeSocket(placeholder);
        return;
      }
      if (head.length > 0) {
        debug('got illegal response body from proxy');
        socket.destroy();
        var error = new Error('got illegal response body from proxy');
        error.code = 'ECONNRESET';
        options.request.emit('error', error);
        self.removeSocket(placeholder);
        return;
      }
      debug('tunneling connection has established');
      self.sockets[self.sockets.indexOf(placeholder)] = socket;
      return cb(socket);
    }
  
    function onError(cause) {
      connectReq.removeAllListeners();
  
      debug('tunneling socket could not be established, cause=%s\n',
            cause.message, cause.stack);
      var error = new Error('tunneling socket could not be established, ' +
                            'cause=' + cause.message);
      error.code = 'ECONNRESET';
      options.request.emit('error', error);
      self.removeSocket(placeholder);
    }
  };
  
  TunnelingAgent.prototype.removeSocket = function removeSocket(socket) {
    var pos = this.sockets.indexOf(socket);
    if (pos === -1) {
      return;
    }
    this.sockets.splice(pos, 1);
  
    var pending = this.requests.shift();
    if (pending) {
      // If we have pending requests and a socket gets closed a new one
      // needs to be created to take over in the pool for the one that closed.
      this.createSocket(pending, function(socket) {
        pending.request.onSocket(socket);
      });
    }
  };
  
  function createSecureSocket(options, cb) {
    var self = this;
    TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {
      var hostHeader = options.request.getHeader('host');
      var tlsOptions = mergeOptions({}, self.options, {
        socket: socket,
        servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host
      });
  
      // 0 is dummy port for v0.6
      var secureSocket = tls.connect(0, tlsOptions);
      self.sockets[self.sockets.indexOf(socket)] = secureSocket;
      cb(secureSocket);
    });
  }
  
  
  function toOptions(host, port, localAddress) {
    if (typeof host === 'string') { // since v0.10
      return {
        host: host,
        port: port,
        localAddress: localAddress
      };
    }
    return host; // for v0.11 or later
  }
  
  function mergeOptions(target) {
    for (var i = 1, len = arguments.length; i < len; ++i) {
      var overrides = arguments[i];
      if (typeof overrides === 'object') {
        var keys = Object.keys(overrides);
        for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {
          var k = keys[j];
          if (overrides[k] !== undefined) {
            target[k] = overrides[k];
          }
        }
      }
    }
    return target;
  }
  
  
  var debug;
  if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
    debug = function() {
      var args = Array.prototype.slice.call(arguments);
      if (typeof args[0] === 'string') {
        args[0] = 'TUNNEL: ' + args[0];
      } else {
        args.unshift('TUNNEL:');
      }
      console.error.apply(console, args);
    };
  } else {
    debug = function() {};
  }
  var debug_1 = debug; // for test
  
  var tunnel = {
  	httpOverHttp: httpOverHttp_1,
  	httpsOverHttp: httpsOverHttp_1,
  	httpOverHttps: httpOverHttps_1,
  	httpsOverHttps: httpsOverHttps_1,
  	debug: debug_1
  };
  
  var tunnel$1 = tunnel;
  
  var httpClient = createCommonjsModule(function (module, exports) {
  Object.defineProperty(exports, "__esModule", { value: true });
  
  
  
  let tunnel;
  var HttpCodes;
  (function (HttpCodes) {
      HttpCodes[HttpCodes["OK"] = 200] = "OK";
      HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices";
      HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently";
      HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved";
      HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther";
      HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified";
      HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy";
      HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy";
      HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect";
      HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect";
      HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest";
      HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized";
      HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired";
      HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden";
      HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound";
      HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed";
      HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable";
      HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
      HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
      HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
      HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
      HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
      HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
      HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
      HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
      HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
      HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
  })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));
  var Headers;
  (function (Headers) {
      Headers["Accept"] = "accept";
      Headers["ContentType"] = "content-type";
  })(Headers = exports.Headers || (exports.Headers = {}));
  var MediaTypes;
  (function (MediaTypes) {
      MediaTypes["ApplicationJson"] = "application/json";
  })(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}));
  /**
   * Returns the proxy URL, depending upon the supplied url and proxy environment variables.
   * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com
   */
  function getProxyUrl(serverUrl) {
      let proxyUrl = proxy.getProxyUrl(new URL(serverUrl));
      return proxyUrl ? proxyUrl.href : '';
  }
  exports.getProxyUrl = getProxyUrl;
  const HttpRedirectCodes = [
      HttpCodes.MovedPermanently,
      HttpCodes.ResourceMoved,
      HttpCodes.SeeOther,
      HttpCodes.TemporaryRedirect,
      HttpCodes.PermanentRedirect
  ];
  const HttpResponseRetryCodes = [
      HttpCodes.BadGateway,
      HttpCodes.ServiceUnavailable,
      HttpCodes.GatewayTimeout
  ];
  const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
  const ExponentialBackoffCeiling = 10;
  const ExponentialBackoffTimeSlice = 5;
  class HttpClientError extends Error {
      constructor(message, statusCode) {
          super(message);
          this.name = 'HttpClientError';
          this.statusCode = statusCode;
          Object.setPrototypeOf(this, HttpClientError.prototype);
      }
  }
  exports.HttpClientError = HttpClientError;
  class HttpClientResponse {
      constructor(message) {
          this.message = message;
      }
      readBody() {
          return new Promise(async (resolve, reject) => {
              let output = Buffer.alloc(0);
              this.message.on('data', (chunk) => {
                  output = Buffer.concat([output, chunk]);
              });
              this.message.on('end', () => {
                  resolve(output.toString());
              });
          });
      }
  }
  exports.HttpClientResponse = HttpClientResponse;
  function isHttps(requestUrl) {
      let parsedUrl = new URL(requestUrl);
      return parsedUrl.protocol === 'https:';
  }
  exports.isHttps = isHttps;
  class HttpClient {
      constructor(userAgent, handlers, requestOptions) {
          this._ignoreSslError = false;
          this._allowRedirects = true;
          this._allowRedirectDowngrade = false;
          this._maxRedirects = 50;
          this._allowRetries = false;
          this._maxRetries = 1;
          this._keepAlive = false;
          this._disposed = false;
          this.userAgent = userAgent;
          this.handlers = handlers || [];
          this.requestOptions = requestOptions;
          if (requestOptions) {
              if (requestOptions.ignoreSslError != null) {
                  this._ignoreSslError = requestOptions.ignoreSslError;
              }
              this._socketTimeout = requestOptions.socketTimeout;
              if (requestOptions.allowRedirects != null) {
                  this._allowRedirects = requestOptions.allowRedirects;
              }
              if (requestOptions.allowRedirectDowngrade != null) {
                  this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;
              }
              if (requestOptions.maxRedirects != null) {
                  this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);
              }
              if (requestOptions.keepAlive != null) {
                  this._keepAlive = requestOptions.keepAlive;
              }
              if (requestOptions.allowRetries != null) {
                  this._allowRetries = requestOptions.allowRetries;
              }
              if (requestOptions.maxRetries != null) {
                  this._maxRetries = requestOptions.maxRetries;
              }
          }
      }
      options(requestUrl, additionalHeaders) {
          return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
      }
      get(requestUrl, additionalHeaders) {
          return this.request('GET', requestUrl, null, additionalHeaders || {});
      }
      del(requestUrl, additionalHeaders) {
          return this.request('DELETE', requestUrl, null, additionalHeaders || {});
      }
      post(requestUrl, data, additionalHeaders) {
          return this.request('POST', requestUrl, data, additionalHeaders || {});
      }
      patch(requestUrl, data, additionalHeaders) {
          return this.request('PATCH', requestUrl, data, additionalHeaders || {});
      }
      put(requestUrl, data, additionalHeaders) {
          return this.request('PUT', requestUrl, data, additionalHeaders || {});
      }
      head(requestUrl, additionalHeaders) {
          return this.request('HEAD', requestUrl, null, additionalHeaders || {});
      }
      sendStream(verb, requestUrl, stream, additionalHeaders) {
          return this.request(verb, requestUrl, stream, additionalHeaders);
      }
      /**
       * Gets a typed object from an endpoint
       * Be aware that not found returns a null.  Other errors (4xx, 5xx) reject the promise
       */
      async getJson(requestUrl, additionalHeaders = {}) {
          additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
          let res = await this.get(requestUrl, additionalHeaders);
          return this._processResponse(res, this.requestOptions);
      }
      async postJson(requestUrl, obj, additionalHeaders = {}) {
          let data = JSON.stringify(obj, null, 2);
          additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
          additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
          let res = await this.post(requestUrl, data, additionalHeaders);
          return this._processResponse(res, this.requestOptions);
      }
      async putJson(requestUrl, obj, additionalHeaders = {}) {
          let data = JSON.stringify(obj, null, 2);
          additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
          additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
          let res = await this.put(requestUrl, data, additionalHeaders);
          return this._processResponse(res, this.requestOptions);
      }
      async patchJson(requestUrl, obj, additionalHeaders = {}) {
          let data = JSON.stringify(obj, null, 2);
          additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
          additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
          let res = await this.patch(requestUrl, data, additionalHeaders);
          return this._processResponse(res, this.requestOptions);
      }
      /**
       * Makes a raw http request.
       * All other methods such as get, post, patch, and request ultimately call this.
       * Prefer get, del, post and patch
       */
      async request(verb, requestUrl, data, headers) {
          if (this._disposed) {
              throw new Error('Client has already been disposed.');
          }
          let parsedUrl = new URL(requestUrl);
          let info = this._prepareRequest(verb, parsedUrl, headers);
          // Only perform retries on reads since writes may not be idempotent.
          let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1
              ? this._maxRetries + 1
              : 1;
          let numTries = 0;
          let response;
          while (numTries < maxTries) {
              response = await this.requestRaw(info, data);
              // Check if it's an authentication challenge
              if (response &&
                  response.message &&
                  response.message.statusCode === HttpCodes.Unauthorized) {
                  let authenticationHandler;
                  for (let i = 0; i < this.handlers.length; i++) {
                      if (this.handlers[i].canHandleAuthentication(response)) {
                          authenticationHandler = this.handlers[i];
                          break;
                      }
                  }
                  if (authenticationHandler) {
                      return authenticationHandler.handleAuthentication(this, info, data);
                  }
                  else {
                      // We have received an unauthorized response but have no handlers to handle it.
                      // Let the response return to the caller.
                      return response;
                  }
              }
              let redirectsRemaining = this._maxRedirects;
              while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&
                  this._allowRedirects &&
                  redirectsRemaining > 0) {
                  const redirectUrl = response.message.headers['location'];
                  if (!redirectUrl) {
                      // if there's no location to redirect to, we won't
                      break;
                  }
                  let parsedRedirectUrl = new URL(redirectUrl);
                  if (parsedUrl.protocol == 'https:' &&
                      parsedUrl.protocol != parsedRedirectUrl.protocol &&
                      !this._allowRedirectDowngrade) {
                      throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');
                  }
                  // we need to finish reading the response before reassigning response
                  // which will leak the open socket.
                  await response.readBody();
                  // strip authorization header if redirected to a different hostname
                  if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
                      for (let header in headers) {
                          // header names are case insensitive
                          if (header.toLowerCase() === 'authorization') {
                              delete headers[header];
                          }
                      }
                  }
                  // let's make the request with the new redirectUrl
                  info = this._prepareRequest(verb, parsedRedirectUrl, headers);
                  response = await this.requestRaw(info, data);
                  redirectsRemaining--;
              }
              if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) {
                  // If not a retry code, return immediately instead of retrying
                  return response;
              }
              numTries += 1;
              if (numTries < maxTries) {
                  await response.readBody();
                  await this._performExponentialBackoff(numTries);
              }
          }
          return response;
      }
      /**
       * Needs to be called if keepAlive is set to true in request options.
       */
      dispose() {
          if (this._agent) {
              this._agent.destroy();
          }
          this._disposed = true;
      }
      /**
       * Raw request.
       * @param info
       * @param data
       */
      requestRaw(info, data) {
          return new Promise((resolve, reject) => {
              let callbackForResult = function (err, res) {
                  if (err) {
                      reject(err);
                  }
                  resolve(res);
              };
              this.requestRawWithCallback(info, data, callbackForResult);
          });
      }
      /**
       * Raw request with callback.
       * @param info
       * @param data
       * @param onResult
       */
      requestRawWithCallback(info, data, onResult) {
          let socket;
          if (typeof data === 'string') {
              info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
          }
          let callbackCalled = false;
          let handleResult = (err, res) => {
              if (!callbackCalled) {
                  callbackCalled = true;
                  onResult(err, res);
              }
          };
          let req = info.httpModule.request(info.options, (msg) => {
              let res = new HttpClientResponse(msg);
              handleResult(null, res);
          });
          req.on('socket', sock => {
              socket = sock;
          });
          // If we ever get disconnected, we want the socket to timeout eventually
          req.setTimeout(this._socketTimeout || 3 * 60000, () => {
              if (socket) {
                  socket.end();
              }
              handleResult(new Error('Request timeout: ' + info.options.path), null);
          });
          req.on('error', function (err) {
              // err has statusCode property
              // res should have headers
              handleResult(err, null);
          });
          if (data && typeof data === 'string') {
              req.write(data, 'utf8');
          }
          if (data && typeof data !== 'string') {
              data.on('close', function () {
                  req.end();
              });
              data.pipe(req);
          }
          else {
              req.end();
          }
      }
      /**
       * Gets an http agent. This function is useful when you need an http agent that handles
       * routing through a proxy server - depending upon the url and proxy environment variables.
       * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com
       */
      getAgent(serverUrl) {
          let parsedUrl = new URL(serverUrl);
          return this._getAgent(parsedUrl);
      }
      _prepareRequest(method, requestUrl, headers) {
          const info = {};
          info.parsedUrl = requestUrl;
          const usingSsl = info.parsedUrl.protocol === 'https:';
          info.httpModule = usingSsl ? https : http;
          const defaultPort = usingSsl ? 443 : 80;
          info.options = {};
          info.options.host = info.parsedUrl.hostname;
          info.options.port = info.parsedUrl.port
              ? parseInt(info.parsedUrl.port)
              : defaultPort;
          info.options.path =
              (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
          info.options.method = method;
          info.options.headers = this._mergeHeaders(headers);
          if (this.userAgent != null) {
              info.options.headers['user-agent'] = this.userAgent;
          }
          info.options.agent = this._getAgent(info.parsedUrl);
          // gives handlers an opportunity to participate
          if (this.handlers) {
              this.handlers.forEach(handler => {
                  handler.prepareRequest(info.options);
              });
          }
          return info;
      }
      _mergeHeaders(headers) {
          const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
          if (this.requestOptions && this.requestOptions.headers) {
              return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
          }
          return lowercaseKeys(headers || {});
      }
      _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
          const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
          let clientHeader;
          if (this.requestOptions && this.requestOptions.headers) {
              clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
          }
          return additionalHeaders[header] || clientHeader || _default;
      }
      _getAgent(parsedUrl) {
          let agent;
          let proxyUrl = proxy.getProxyUrl(parsedUrl);
          let useProxy = proxyUrl && proxyUrl.hostname;
          if (this._keepAlive && useProxy) {
              agent = this._proxyAgent;
          }
          if (this._keepAlive && !useProxy) {
              agent = this._agent;
          }
          // if agent is already assigned use that agent.
          if (!!agent) {
              return agent;
          }
          const usingSsl = parsedUrl.protocol === 'https:';
          let maxSockets = 100;
          if (!!this.requestOptions) {
              maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;
          }
          if (useProxy) {
              // If using proxy, need tunnel
              if (!tunnel) {
                  tunnel = tunnel$1;
              }
              const agentOptions = {
                  maxSockets: maxSockets,
                  keepAlive: this._keepAlive,
                  proxy: {
                      proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`,
                      host: proxyUrl.hostname,
                      port: proxyUrl.port
                  }
              };
              let tunnelAgent;
              const overHttps = proxyUrl.protocol === 'https:';
              if (usingSsl) {
                  tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;
              }
              else {
                  tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;
              }
              agent = tunnelAgent(agentOptions);
              this._proxyAgent = agent;
          }
          // if reusing agent across request and tunneling agent isn't assigned create a new agent
          if (this._keepAlive && !agent) {
              const options = { keepAlive: this._keepAlive, maxSockets: maxSockets };
              agent = usingSsl ? new https.Agent(options) : new http.Agent(options);
              this._agent = agent;
          }
          // if not using private agent and tunnel agent isn't setup then use global agent
          if (!agent) {
              agent = usingSsl ? https.globalAgent : http.globalAgent;
          }
          if (usingSsl && this._ignoreSslError) {
              // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
              // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
              // we have to cast it to any and change it directly
              agent.options = Object.assign(agent.options || {}, {
                  rejectUnauthorized: false
              });
          }
          return agent;
      }
      _performExponentialBackoff(retryNumber) {
          retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
          const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
          return new Promise(resolve => setTimeout(() => resolve(), ms));
      }
      static dateTimeDeserializer(key, value) {
          if (typeof value === 'string') {
              let a = new Date(value);
              if (!isNaN(a.valueOf())) {
                  return a;
              }
          }
          return value;
      }
      async _processResponse(res, options) {
          return new Promise(async (resolve, reject) => {
              const statusCode = res.message.statusCode;
              const response = {
                  statusCode: statusCode,
                  result: null,
                  headers: {}
              };
              // not found leads to null obj returned
              if (statusCode == HttpCodes.NotFound) {
                  resolve(response);
              }
              let obj;
              let contents;
              // get the result from the body
              try {
                  contents = await res.readBody();
                  if (contents && contents.length > 0) {
                      if (options && options.deserializeDates) {
                          obj = JSON.parse(contents, HttpClient.dateTimeDeserializer);
                      }
                      else {
                          obj = JSON.parse(contents);
                      }
                      response.result = obj;
                  }
                  response.headers = res.message.headers;
              }
              catch (err) {
                  // Invalid resource (contents not json);  leaving result obj null
              }
              // note that 3xx redirects are handled by the http layer.
              if (statusCode > 299) {
                  let msg;
                  // if exception/error in body, attempt to get better error
                  if (obj && obj.message) {
                      msg = obj.message;
                  }
                  else if (contents && contents.length > 0) {
                      // it may be the case that the exception is in the body message as string
                      msg = contents;
                  }
                  else {
                      msg = 'Failed request: (' + statusCode + ')';
                  }
                  let err = new HttpClientError(msg, statusCode);
                  err.result = response.result;
                  reject(err);
              }
              else {
                  resolve(response);
              }
          });
      }
  }
  exports.HttpClient = HttpClient;
  });
  
  var utils$1 = createCommonjsModule(function (module, exports) {
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) {
      Object.defineProperty(o, "default", { enumerable: true, value: v });
  }) : function(o, v) {
      o["default"] = v;
  });
  var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
      __setModuleDefault(result, mod);
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0;
  const httpClient$1 = __importStar(httpClient);
  function getAuthString(token, options) {
      if (!token && !options.auth) {
          throw new Error('Parameter token or opts.auth is required');
      }
      else if (token && options.auth) {
          throw new Error('Parameters token and opts.auth may not both be specified');
      }
      return typeof options.auth === 'string' ? options.auth : `token ${token}`;
  }
  exports.getAuthString = getAuthString;
  function getProxyAgent(destinationUrl) {
      const hc = new httpClient$1.HttpClient();
      return hc.getAgent(destinationUrl);
  }
  exports.getProxyAgent = getProxyAgent;
  function getApiBaseUrl() {
      return process.env['GITHUB_API_URL'] || 'https://api.github.com';
  }
  exports.getApiBaseUrl = getApiBaseUrl;
  
  });
  
  function getUserAgent() {
      if (typeof navigator === "object" && "userAgent" in navigator) {
          return navigator.userAgent;
      }
      if (typeof process === "object" && "version" in process) {
          return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`;
      }
      return "<environment undetectable>";
  }
  
  var register_1 = register;
  
  function register (state, name, method, options) {
    if (typeof method !== 'function') {
      throw new Error('method for before hook must be a function')
    }
  
    if (!options) {
      options = {};
    }
  
    if (Array.isArray(name)) {
      return name.reverse().reduce(function (callback, name) {
        return register.bind(null, state, name, callback, options)
      }, method)()
    }
  
    return Promise.resolve()
      .then(function () {
        if (!state.registry[name]) {
          return method(options)
        }
  
        return (state.registry[name]).reduce(function (method, registered) {
          return registered.hook.bind(null, method, options)
        }, method)()
      })
  }
  
  var add = addHook;
  
  function addHook (state, kind, name, hook) {
    var orig = hook;
    if (!state.registry[name]) {
      state.registry[name] = [];
    }
  
    if (kind === 'before') {
      hook = function (method, options) {
        return Promise.resolve()
          .then(orig.bind(null, options))
          .then(method.bind(null, options))
      };
    }
  
    if (kind === 'after') {
      hook = function (method, options) {
        var result;
        return Promise.resolve()
          .then(method.bind(null, options))
          .then(function (result_) {
            result = result_;
            return orig(result, options)
          })
          .then(function () {
            return result
          })
      };
    }
  
    if (kind === 'error') {
      hook = function (method, options) {
        return Promise.resolve()
          .then(method.bind(null, options))
          .catch(function (error) {
            return orig(error, options)
          })
      };
    }
  
    state.registry[name].push({
      hook: hook,
      orig: orig
    });
  }
  
  var remove = removeHook;
  
  function removeHook (state, name, method) {
    if (!state.registry[name]) {
      return
    }
  
    var index = state.registry[name]
      .map(function (registered) { return registered.orig })
      .indexOf(method);
  
    if (index === -1) {
      return
    }
  
    state.registry[name].splice(index, 1);
  }
  
  // bind with array of arguments: https://stackoverflow.com/a/21792913
  var bind = Function.bind;
  var bindable = bind.bind(bind);
  
  function bindApi (hook, state, name) {
    var removeHookRef = bindable(remove, null).apply(null, name ? [state, name] : [state]);
    hook.api = { remove: removeHookRef };
    hook.remove = removeHookRef
  
    ;['before', 'error', 'after', 'wrap'].forEach(function (kind) {
      var args = name ? [state, kind, name] : [state, kind];
      hook[kind] = hook.api[kind] = bindable(add, null).apply(null, args);
    });
  }
  
  function HookSingular () {
    var singularHookName = 'h';
    var singularHookState = {
      registry: {}
    };
    var singularHook = register_1.bind(null, singularHookState, singularHookName);
    bindApi(singularHook, singularHookState, singularHookName);
    return singularHook
  }
  
  function HookCollection () {
    var state = {
      registry: {}
    };
  
    var hook = register_1.bind(null, state);
    bindApi(hook, state);
  
    return hook
  }
  
  var collectionHookDeprecationMessageDisplayed = false;
  function Hook () {
    if (!collectionHookDeprecationMessageDisplayed) {
      console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4');
      collectionHookDeprecationMessageDisplayed = true;
    }
    return HookCollection()
  }
  
  Hook.Singular = HookSingular.bind();
  Hook.Collection = HookCollection.bind();
  
  var beforeAfterHook = Hook;
  // expose constructors as a named property for TypeScript
  var Hook_1 = Hook;
  var Singular = Hook.Singular;
  var Collection = Hook.Collection;
  beforeAfterHook.Hook = Hook_1;
  beforeAfterHook.Singular = Singular;
  beforeAfterHook.Collection = Collection;
  
  /*!
   * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
   *
   * Copyright (c) 2014-2017, Jon Schlinkert.
   * Released under the MIT License.
   */
  
  function isObject(o) {
    return Object.prototype.toString.call(o) === '[object Object]';
  }
  
  function isPlainObject(o) {
    var ctor,prot;
  
    if (isObject(o) === false) return false;
  
    // If has modified constructor
    ctor = o.constructor;
    if (ctor === undefined) return true;
  
    // If has modified prototype
    prot = ctor.prototype;
    if (isObject(prot) === false) return false;
  
    // If constructor does not have an Object-specific method
    if (prot.hasOwnProperty('isPrototypeOf') === false) {
      return false;
    }
  
    // Most likely a plain Object
    return true;
  }
  
  function lowercaseKeys$1(object) {
      if (!object) {
          return {};
      }
      return Object.keys(object).reduce((newObj, key) => {
          newObj[key.toLowerCase()] = object[key];
          return newObj;
      }, {});
  }
  
  function mergeDeep(defaults, options) {
      const result = Object.assign({}, defaults);
      Object.keys(options).forEach((key) => {
          if (isPlainObject(options[key])) {
              if (!(key in defaults))
                  Object.assign(result, { [key]: options[key] });
              else
                  result[key] = mergeDeep(defaults[key], options[key]);
          }
          else {
              Object.assign(result, { [key]: options[key] });
          }
      });
      return result;
  }
  
  function removeUndefinedProperties(obj) {
      for (const key in obj) {
          if (obj[key] === undefined) {
              delete obj[key];
          }
      }
      return obj;
  }
  
  function merge(defaults, route, options) {
      if (typeof route === "string") {
          let [method, url] = route.split(" ");
          options = Object.assign(url ? { method, url } : { url: method }, options);
      }
      else {
          options = Object.assign({}, route);
      }
      // lowercase header names before merging with defaults to avoid duplicates
      options.headers = lowercaseKeys$1(options.headers);
      // remove properties with undefined values before merging
      removeUndefinedProperties(options);
      removeUndefinedProperties(options.headers);
      const mergedOptions = mergeDeep(defaults || {}, options);
      // mediaType.previews arrays are merged, instead of overwritten
      if (defaults && defaults.mediaType.previews.length) {
          mergedOptions.mediaType.previews = defaults.mediaType.previews
              .filter((preview) => !mergedOptions.mediaType.previews.includes(preview))
              .concat(mergedOptions.mediaType.previews);
      }
      mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map((preview) => preview.replace(/-preview/, ""));
      return mergedOptions;
  }
  
  function addQueryParameters(url, parameters) {
      const separator = /\?/.test(url) ? "&" : "?";
      const names = Object.keys(parameters);
      if (names.length === 0) {
          return url;
      }
      return (url +
          separator +
          names
              .map((name) => {
              if (name === "q") {
                  return ("q=" + parameters.q.split("+").map(encodeURIComponent).join("+"));
              }
              return `${name}=${encodeURIComponent(parameters[name])}`;
          })
              .join("&"));
  }
  
  const urlVariableRegex = /\{[^}]+\}/g;
  function removeNonChars(variableName) {
      return variableName.replace(/^\W+|\W+$/g, "").split(/,/);
  }
  function extractUrlVariableNames(url) {
      const matches = url.match(urlVariableRegex);
      if (!matches) {
          return [];
      }
      return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);
  }
  
  function omit(object, keysToOmit) {
      return Object.keys(object)
          .filter((option) => !keysToOmit.includes(option))
          .reduce((obj, key) => {
          obj[key] = object[key];
          return obj;
      }, {});
  }
  
  // Based on https://github.com/bramstein/url-template, licensed under BSD
  // TODO: create separate package.
  //
  // Copyright (c) 2012-2014, Bram Stein
  // All rights reserved.
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions
  // are met:
  //  1. Redistributions of source code must retain the above copyright
  //     notice, this list of conditions and the following disclaimer.
  //  2. Redistributions in binary form must reproduce the above copyright
  //     notice, this list of conditions and the following disclaimer in the
  //     documentation and/or other materials provided with the distribution.
  //  3. The name of the author may not be used to endorse or promote products
  //     derived from this software without specific prior written permission.
  // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
  // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  // EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  /* istanbul ignore file */
  function encodeReserved(str) {
      return str
          .split(/(%[0-9A-Fa-f]{2})/g)
          .map(function (part) {
          if (!/%[0-9A-Fa-f]/.test(part)) {
              part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]");
          }
          return part;
      })
          .join("");
  }
  function encodeUnreserved(str) {
      return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
          return "%" + c.charCodeAt(0).toString(16).toUpperCase();
      });
  }
  function encodeValue(operator, value, key) {
      value =
          operator === "+" || operator === "#"
              ? encodeReserved(value)
              : encodeUnreserved(value);
      if (key) {
          return encodeUnreserved(key) + "=" + value;
      }
      else {
          return value;
      }
  }
  function isDefined(value) {
      return value !== undefined && value !== null;
  }
  function isKeyOperator(operator) {
      return operator === ";" || operator === "&" || operator === "?";
  }
  function getValues(context, operator, key, modifier) {
      var value = context[key], result = [];
      if (isDefined(value) && value !== "") {
          if (typeof value === "string" ||
              typeof value === "number" ||
              typeof value === "boolean") {
              value = value.toString();
              if (modifier && modifier !== "*") {
                  value = value.substring(0, parseInt(modifier, 10));
              }
              result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : ""));
          }
          else {
              if (modifier === "*") {
                  if (Array.isArray(value)) {
                      value.filter(isDefined).forEach(function (value) {
                          result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : ""));
                      });
                  }
                  else {
                      Object.keys(value).forEach(function (k) {
                          if (isDefined(value[k])) {
                              result.push(encodeValue(operator, value[k], k));
                          }
                      });
                  }
              }
              else {
                  const tmp = [];
                  if (Array.isArray(value)) {
                      value.filter(isDefined).forEach(function (value) {
                          tmp.push(encodeValue(operator, value));
                      });
                  }
                  else {
                      Object.keys(value).forEach(function (k) {
                          if (isDefined(value[k])) {
                              tmp.push(encodeUnreserved(k));
                              tmp.push(encodeValue(operator, value[k].toString()));
                          }
                      });
                  }
                  if (isKeyOperator(operator)) {
                      result.push(encodeUnreserved(key) + "=" + tmp.join(","));
                  }
                  else if (tmp.length !== 0) {
                      result.push(tmp.join(","));
                  }
              }
          }
      }
      else {
          if (operator === ";") {
              if (isDefined(value)) {
                  result.push(encodeUnreserved(key));
              }
          }
          else if (value === "" && (operator === "&" || operator === "?")) {
              result.push(encodeUnreserved(key) + "=");
          }
          else if (value === "") {
              result.push("");
          }
      }
      return result;
  }
  function parseUrl(template) {
      return {
          expand: expand.bind(null, template),
      };
  }
  function expand(template, context) {
      var operators = ["+", "#", ".", "/", ";", "?", "&"];
      return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
          if (expression) {
              let operator = "";
              const values = [];
              if (operators.indexOf(expression.charAt(0)) !== -1) {
                  operator = expression.charAt(0);
                  expression = expression.substr(1);
              }
              expression.split(/,/g).forEach(function (variable) {
                  var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
                  values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
              });
              if (operator && operator !== "+") {
                  var separator = ",";
                  if (operator === "?") {
                      separator = "&";
                  }
                  else if (operator !== "#") {
                      separator = operator;
                  }
                  return (values.length !== 0 ? operator : "") + values.join(separator);
              }
              else {
                  return values.join(",");
              }
          }
          else {
              return encodeReserved(literal);
          }
      });
  }
  
  function parse$1(options) {
      // https://fetch.spec.whatwg.org/#methods
      let method = options.method.toUpperCase();
      // replace :varname with {varname} to make it RFC 6570 compatible
      let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}");
      let headers = Object.assign({}, options.headers);
      let body;
      let parameters = omit(options, [
          "method",
          "baseUrl",
          "url",
          "headers",
          "request",
          "mediaType",
      ]);
      // extract variable names from URL to calculate remaining variables later
      const urlVariableNames = extractUrlVariableNames(url);
      url = parseUrl(url).expand(parameters);
      if (!/^http/.test(url)) {
          url = options.baseUrl + url;
      }
      const omittedParameters = Object.keys(options)
          .filter((option) => urlVariableNames.includes(option))
          .concat("baseUrl");
      const remainingParameters = omit(parameters, omittedParameters);
      const isBinaryRequest = /application\/octet-stream/i.test(headers.accept);
      if (!isBinaryRequest) {
          if (options.mediaType.format) {
              // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw
              headers.accept = headers.accept
                  .split(/,/)
                  .map((preview) => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`))
                  .join(",");
          }
          if (options.mediaType.previews.length) {
              const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
              headers.accept = previewsFromAcceptHeader
                  .concat(options.mediaType.previews)
                  .map((preview) => {
                  const format = options.mediaType.format
                      ? `.${options.mediaType.format}`
                      : "+json";
                  return `application/vnd.github.${preview}-preview${format}`;
              })
                  .join(",");
          }
      }
      // for GET/HEAD requests, set URL query parameters from remaining parameters
      // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
      if (["GET", "HEAD"].includes(method)) {
          url = addQueryParameters(url, remainingParameters);
      }
      else {
          if ("data" in remainingParameters) {
              body = remainingParameters.data;
          }
          else {
              if (Object.keys(remainingParameters).length) {
                  body = remainingParameters;
              }
              else {
                  headers["content-length"] = 0;
              }
          }
      }
      // default content-type for JSON if body is set
      if (!headers["content-type"] && typeof body !== "undefined") {
          headers["content-type"] = "application/json; charset=utf-8";
      }
      // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
      // fetch does not allow to set `content-length` header, but we can set body to an empty string
      if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") {
          body = "";
      }
      // Only return body/request keys if present
      return Object.assign({ method, url, headers }, typeof body !== "undefined" ? { body } : null, options.request ? { request: options.request } : null);
  }
  
  function endpointWithDefaults(defaults, route, options) {
      return parse$1(merge(defaults, route, options));
  }
  
  function withDefaults(oldDefaults, newDefaults) {
      const DEFAULTS = merge(oldDefaults, newDefaults);
      const endpoint = endpointWithDefaults.bind(null, DEFAULTS);
      return Object.assign(endpoint, {
          DEFAULTS,
          defaults: withDefaults.bind(null, DEFAULTS),
          merge: merge.bind(null, DEFAULTS),
          parse: parse$1,
      });
  }
  
  const VERSION = "6.0.8";
  
  const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`;
  // DEFAULTS has all properties set that EndpointOptions has, except url.
  // So we use RequestParameters and add method as additional required property.
  const DEFAULTS = {
      method: "GET",
      baseUrl: "https://api.github.com",
      headers: {
          accept: "application/vnd.github.v3+json",
          "user-agent": userAgent,
      },
      mediaType: {
          format: "",
          previews: [],
      },
  };
  
  const endpoint = withDefaults(null, DEFAULTS);
  
  // Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
  
  // fix for "Readable" isn't a named export issue
  const Readable$2 = Stream.Readable;
  
  const BUFFER = Symbol('buffer');
  const TYPE = Symbol('type');
  
  class Blob {
  	constructor() {
  		this[TYPE] = '';
  
  		const blobParts = arguments[0];
  		const options = arguments[1];
  
  		const buffers = [];
  
  		if (blobParts) {
  			const a = blobParts;
  			const length = Number(a.length);
  			for (let i = 0; i < length; i++) {
  				const element = a[i];
  				let buffer;
  				if (element instanceof Buffer) {
  					buffer = element;
  				} else if (ArrayBuffer.isView(element)) {
  					buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);
  				} else if (element instanceof ArrayBuffer) {
  					buffer = Buffer.from(element);
  				} else if (element instanceof Blob) {
  					buffer = element[BUFFER];
  				} else {
  					buffer = Buffer.from(typeof element === 'string' ? element : String(element));
  				}
  				buffers.push(buffer);
  			}
  		}
  
  		this[BUFFER] = Buffer.concat(buffers);
  
  		let type = options && options.type !== undefined && String(options.type).toLowerCase();
  		if (type && !/[^\u0020-\u007E]/.test(type)) {
  			this[TYPE] = type;
  		}
  	}
  	get size() {
  		return this[BUFFER].length;
  	}
  	get type() {
  		return this[TYPE];
  	}
  	text() {
  		return Promise.resolve(this[BUFFER].toString());
  	}
  	arrayBuffer() {
  		const buf = this[BUFFER];
  		const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
  		return Promise.resolve(ab);
  	}
  	stream() {
  		const readable = new Readable$2();
  		readable._read = function () {};
  		readable.push(this[BUFFER]);
  		readable.push(null);
  		return readable;
  	}
  	toString() {
  		return '[object Blob]';
  	}
  	slice() {
  		const size = this.size;
  
  		const start = arguments[0];
  		const end = arguments[1];
  		let relativeStart, relativeEnd;
  		if (start === undefined) {
  			relativeStart = 0;
  		} else if (start < 0) {
  			relativeStart = Math.max(size + start, 0);
  		} else {
  			relativeStart = Math.min(start, size);
  		}
  		if (end === undefined) {
  			relativeEnd = size;
  		} else if (end < 0) {
  			relativeEnd = Math.max(size + end, 0);
  		} else {
  			relativeEnd = Math.min(end, size);
  		}
  		const span = Math.max(relativeEnd - relativeStart, 0);
  
  		const buffer = this[BUFFER];
  		const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
  		const blob = new Blob([], { type: arguments[2] });
  		blob[BUFFER] = slicedBuffer;
  		return blob;
  	}
  }
  
  Object.defineProperties(Blob.prototype, {
  	size: { enumerable: true },
  	type: { enumerable: true },
  	slice: { enumerable: true }
  });
  
  Object.defineProperty(Blob.prototype, Symbol.toStringTag, {
  	value: 'Blob',
  	writable: false,
  	enumerable: false,
  	configurable: true
  });
  
  /**
   * fetch-error.js
   *
   * FetchError interface for operational errors
   */
  
  /**
   * Create FetchError instance
   *
   * @param   String      message      Error message for human
   * @param   String      type         Error type for machine
   * @param   String      systemError  For Node.js system error
   * @return  FetchError
   */
  function FetchError(message, type, systemError) {
    Error.call(this, message);
  
    this.message = message;
    this.type = type;
  
    // when err.type is `system`, err.code contains system error code
    if (systemError) {
      this.code = this.errno = systemError.code;
    }
  
    // hide custom error implementation details from end-users
    Error.captureStackTrace(this, this.constructor);
  }
  
  FetchError.prototype = Object.create(Error.prototype);
  FetchError.prototype.constructor = FetchError;
  FetchError.prototype.name = 'FetchError';
  
  let convert;
  try {
  	convert = require('encoding').convert;
  } catch (e) {}
  
  const INTERNALS = Symbol('Body internals');
  
  // fix an issue where "PassThrough" isn't a named export for node <10
  const PassThrough$2 = Stream.PassThrough;
  
  /**
   * Body mixin
   *
   * Ref: https://fetch.spec.whatwg.org/#body
   *
   * @param   Stream  body  Readable stream
   * @param   Object  opts  Response options
   * @return  Void
   */
  function Body(body) {
  	var _this = this;
  
  	var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
  	    _ref$size = _ref.size;
  
  	let size = _ref$size === undefined ? 0 : _ref$size;
  	var _ref$timeout = _ref.timeout;
  	let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
  
  	if (body == null) {
  		// body is undefined or null
  		body = null;
  	} else if (isURLSearchParams(body)) {
  		// body is a URLSearchParams
  		body = Buffer.from(body.toString());
  	} else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
  		// body is ArrayBuffer
  		body = Buffer.from(body);
  	} else if (ArrayBuffer.isView(body)) {
  		// body is ArrayBufferView
  		body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
  	} else if (body instanceof Stream) ; else {
  		// none of the above
  		// coerce to string then buffer
  		body = Buffer.from(String(body));
  	}
  	this[INTERNALS] = {
  		body,
  		disturbed: false,
  		error: null
  	};
  	this.size = size;
  	this.timeout = timeout;
  
  	if (body instanceof Stream) {
  		body.on('error', function (err) {
  			const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);
  			_this[INTERNALS].error = error;
  		});
  	}
  }
  
  Body.prototype = {
  	get body() {
  		return this[INTERNALS].body;
  	},
  
  	get bodyUsed() {
  		return this[INTERNALS].disturbed;
  	},
  
  	/**
    * Decode response as ArrayBuffer
    *
    * @return  Promise
    */
  	arrayBuffer() {
  		return consumeBody.call(this).then(function (buf) {
  			return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
  		});
  	},
  
  	/**
    * Return raw response as Blob
    *
    * @return Promise
    */
  	blob() {
  		let ct = this.headers && this.headers.get('content-type') || '';
  		return consumeBody.call(this).then(function (buf) {
  			return Object.assign(
  			// Prevent copying
  			new Blob([], {
  				type: ct.toLowerCase()
  			}), {
  				[BUFFER]: buf
  			});
  		});
  	},
  
  	/**
    * Decode response as json
    *
    * @return  Promise
    */
  	json() {
  		var _this2 = this;
  
  		return consumeBody.call(this).then(function (buffer) {
  			try {
  				return JSON.parse(buffer.toString());
  			} catch (err) {
  				return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));
  			}
  		});
  	},
  
  	/**
    * Decode response as text
    *
    * @return  Promise
    */
  	text() {
  		return consumeBody.call(this).then(function (buffer) {
  			return buffer.toString();
  		});
  	},
  
  	/**
    * Decode response as buffer (non-spec api)
    *
    * @return  Promise
    */
  	buffer() {
  		return consumeBody.call(this);
  	},
  
  	/**
    * Decode response as text, while automatically detecting the encoding and
    * trying to decode to UTF-8 (non-spec api)
    *
    * @return  Promise
    */
  	textConverted() {
  		var _this3 = this;
  
  		return consumeBody.call(this).then(function (buffer) {
  			return convertBody(buffer, _this3.headers);
  		});
  	}
  };
  
  // In browsers, all properties are enumerable.
  Object.defineProperties(Body.prototype, {
  	body: { enumerable: true },
  	bodyUsed: { enumerable: true },
  	arrayBuffer: { enumerable: true },
  	blob: { enumerable: true },
  	json: { enumerable: true },
  	text: { enumerable: true }
  });
  
  Body.mixIn = function (proto) {
  	for (const name of Object.getOwnPropertyNames(Body.prototype)) {
  		// istanbul ignore else: future proof
  		if (!(name in proto)) {
  			const desc = Object.getOwnPropertyDescriptor(Body.prototype, name);
  			Object.defineProperty(proto, name, desc);
  		}
  	}
  };
  
  /**
   * Consume and convert an entire Body to a Buffer.
   *
   * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
   *
   * @return  Promise
   */
  function consumeBody() {
  	var _this4 = this;
  
  	if (this[INTERNALS].disturbed) {
  		return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));
  	}
  
  	this[INTERNALS].disturbed = true;
  
  	if (this[INTERNALS].error) {
  		return Body.Promise.reject(this[INTERNALS].error);
  	}
  
  	let body = this.body;
  
  	// body is null
  	if (body === null) {
  		return Body.Promise.resolve(Buffer.alloc(0));
  	}
  
  	// body is blob
  	if (isBlob(body)) {
  		body = body.stream();
  	}
  
  	// body is buffer
  	if (Buffer.isBuffer(body)) {
  		return Body.Promise.resolve(body);
  	}
  
  	// istanbul ignore if: should never happen
  	if (!(body instanceof Stream)) {
  		return Body.Promise.resolve(Buffer.alloc(0));
  	}
  
  	// body is stream
  	// get ready to actually consume the body
  	let accum = [];
  	let accumBytes = 0;
  	let abort = false;
  
  	return new Body.Promise(function (resolve, reject) {
  		let resTimeout;
  
  		// allow timeout on slow response body
  		if (_this4.timeout) {
  			resTimeout = setTimeout(function () {
  				abort = true;
  				reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));
  			}, _this4.timeout);
  		}
  
  		// handle stream errors
  		body.on('error', function (err) {
  			if (err.name === 'AbortError') {
  				// if the request was aborted, reject with this Error
  				abort = true;
  				reject(err);
  			} else {
  				// other errors, such as incorrect content-encoding
  				reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));
  			}
  		});
  
  		body.on('data', function (chunk) {
  			if (abort || chunk === null) {
  				return;
  			}
  
  			if (_this4.size && accumBytes + chunk.length > _this4.size) {
  				abort = true;
  				reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));
  				return;
  			}
  
  			accumBytes += chunk.length;
  			accum.push(chunk);
  		});
  
  		body.on('end', function () {
  			if (abort) {
  				return;
  			}
  
  			clearTimeout(resTimeout);
  
  			try {
  				resolve(Buffer.concat(accum, accumBytes));
  			} catch (err) {
  				// handle streams that have accumulated too much data (issue #414)
  				reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));
  			}
  		});
  	});
  }
  
  /**
   * Detect buffer encoding and convert to target encoding
   * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding
   *
   * @param   Buffer  buffer    Incoming buffer
   * @param   String  encoding  Target encoding
   * @return  String
   */
  function convertBody(buffer, headers) {
  	if (typeof convert !== 'function') {
  		throw new Error('The package `encoding` must be installed to use the textConverted() function');
  	}
  
  	const ct = headers.get('content-type');
  	let charset = 'utf-8';
  	let res, str;
  
  	// header
  	if (ct) {
  		res = /charset=([^;]*)/i.exec(ct);
  	}
  
  	// no charset in content type, peek at response body for at most 1024 bytes
  	str = buffer.slice(0, 1024).toString();
  
  	// html5
  	if (!res && str) {
  		res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
  	}
  
  	// html4
  	if (!res && str) {
  		res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);
  		if (!res) {
  			res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str);
  			if (res) {
  				res.pop(); // drop last quote
  			}
  		}
  
  		if (res) {
  			res = /charset=(.*)/i.exec(res.pop());
  		}
  	}
  
  	// xml
  	if (!res && str) {
  		res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
  	}
  
  	// found charset
  	if (res) {
  		charset = res.pop();
  
  		// prevent decode issues when sites use incorrect encoding
  		// ref: https://hsivonen.fi/encoding-menu/
  		if (charset === 'gb2312' || charset === 'gbk') {
  			charset = 'gb18030';
  		}
  	}
  
  	// turn raw buffers into a single utf-8 buffer
  	return convert(buffer, 'UTF-8', charset).toString();
  }
  
  /**
   * Detect a URLSearchParams object
   * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143
   *
   * @param   Object  obj     Object to detect by type or brand
   * @return  String
   */
  function isURLSearchParams(obj) {
  	// Duck-typing as a necessary condition.
  	if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {
  		return false;
  	}
  
  	// Brand-checking and more duck-typing as optional condition.
  	return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';
  }
  
  /**
   * Check if `obj` is a W3C `Blob` object (which `File` inherits from)
   * @param  {*} obj
   * @return {boolean}
   */
  function isBlob(obj) {
  	return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]);
  }
  
  /**
   * Clone body given Res/Req instance
   *
   * @param   Mixed  instance  Response or Request instance
   * @return  Mixed
   */
  function clone(instance) {
  	let p1, p2;
  	let body = instance.body;
  
  	// don't allow cloning a used body
  	if (instance.bodyUsed) {
  		throw new Error('cannot clone body after it is used');
  	}
  
  	// check that body is a stream and not form-data object
  	// note: we can't clone the form-data object without having it as a dependency
  	if (body instanceof Stream && typeof body.getBoundary !== 'function') {
  		// tee instance body
  		p1 = new PassThrough$2();
  		p2 = new PassThrough$2();
  		body.pipe(p1);
  		body.pipe(p2);
  		// set instance body to teed body and return the other teed body
  		instance[INTERNALS].body = p1;
  		body = p2;
  	}
  
  	return body;
  }
  
  /**
   * Performs the operation "extract a `Content-Type` value from |object|" as
   * specified in the specification:
   * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
   *
   * This function assumes that instance.body is present.
   *
   * @param   Mixed  instance  Any options.body input
   */
  function extractContentType(body) {
  	if (body === null) {
  		// body is null
  		return null;
  	} else if (typeof body === 'string') {
  		// body is string
  		return 'text/plain;charset=UTF-8';
  	} else if (isURLSearchParams(body)) {
  		// body is a URLSearchParams
  		return 'application/x-www-form-urlencoded;charset=UTF-8';
  	} else if (isBlob(body)) {
  		// body is blob
  		return body.type || null;
  	} else if (Buffer.isBuffer(body)) {
  		// body is buffer
  		return null;
  	} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
  		// body is ArrayBuffer
  		return null;
  	} else if (ArrayBuffer.isView(body)) {
  		// body is ArrayBufferView
  		return null;
  	} else if (typeof body.getBoundary === 'function') {
  		// detect form data input from form-data module
  		return `multipart/form-data;boundary=${body.getBoundary()}`;
  	} else if (body instanceof Stream) {
  		// body is stream
  		// can't really do much about this
  		return null;
  	} else {
  		// Body constructor defaults other things to string
  		return 'text/plain;charset=UTF-8';
  	}
  }
  
  /**
   * The Fetch Standard treats this as if "total bytes" is a property on the body.
   * For us, we have to explicitly get it with a function.
   *
   * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
   *
   * @param   Body    instance   Instance of Body
   * @return  Number?            Number of bytes, or null if not possible
   */
  function getTotalBytes(instance) {
  	const body = instance.body;
  
  
  	if (body === null) {
  		// body is null
  		return 0;
  	} else if (isBlob(body)) {
  		return body.size;
  	} else if (Buffer.isBuffer(body)) {
  		// body is buffer
  		return body.length;
  	} else if (body && typeof body.getLengthSync === 'function') {
  		// detect form data input from form-data module
  		if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x
  		body.hasKnownLength && body.hasKnownLength()) {
  			// 2.x
  			return body.getLengthSync();
  		}
  		return null;
  	} else {
  		// body is stream
  		return null;
  	}
  }
  
  /**
   * Write a Body to a Node.js WritableStream (e.g. http.Request) object.
   *
   * @param   Body    instance   Instance of Body
   * @return  Void
   */
  function writeToStream(dest, instance) {
  	const body = instance.body;
  
  
  	if (body === null) {
  		// body is null
  		dest.end();
  	} else if (isBlob(body)) {
  		body.stream().pipe(dest);
  	} else if (Buffer.isBuffer(body)) {
  		// body is buffer
  		dest.write(body);
  		dest.end();
  	} else {
  		// body is stream
  		body.pipe(dest);
  	}
  }
  
  // expose Promise
  Body.Promise = global.Promise;
  
  /**
   * headers.js
   *
   * Headers class offers convenient helpers
   */
  
  const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
  const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
  
  function validateName(name) {
  	name = `${name}`;
  	if (invalidTokenRegex.test(name) || name === '') {
  		throw new TypeError(`${name} is not a legal HTTP header name`);
  	}
  }
  
  function validateValue(value) {
  	value = `${value}`;
  	if (invalidHeaderCharRegex.test(value)) {
  		throw new TypeError(`${value} is not a legal HTTP header value`);
  	}
  }
  
  /**
   * Find the key in the map object given a header name.
   *
   * Returns undefined if not found.
   *
   * @param   String  name  Header name
   * @return  String|Undefined
   */
  function find(map, name) {
  	name = name.toLowerCase();
  	for (const key in map) {
  		if (key.toLowerCase() === name) {
  			return key;
  		}
  	}
  	return undefined;
  }
  
  const MAP = Symbol('map');
  class Headers {
  	/**
    * Headers class
    *
    * @param   Object  headers  Response headers
    * @return  Void
    */
  	constructor() {
  		let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
  
  		this[MAP] = Object.create(null);
  
  		if (init instanceof Headers) {
  			const rawHeaders = init.raw();
  			const headerNames = Object.keys(rawHeaders);
  
  			for (const headerName of headerNames) {
  				for (const value of rawHeaders[headerName]) {
  					this.append(headerName, value);
  				}
  			}
  
  			return;
  		}
  
  		// We don't worry about converting prop to ByteString here as append()
  		// will handle it.
  		if (init == null) ; else if (typeof init === 'object') {
  			const method = init[Symbol.iterator];
  			if (method != null) {
  				if (typeof method !== 'function') {
  					throw new TypeError('Header pairs must be iterable');
  				}
  
  				// sequence<sequence<ByteString>>
  				// Note: per spec we have to first exhaust the lists then process them
  				const pairs = [];
  				for (const pair of init) {
  					if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
  						throw new TypeError('Each header pair must be iterable');
  					}
  					pairs.push(Array.from(pair));
  				}
  
  				for (const pair of pairs) {
  					if (pair.length !== 2) {
  						throw new TypeError('Each header pair must be a name/value tuple');
  					}
  					this.append(pair[0], pair[1]);
  				}
  			} else {
  				// record<ByteString, ByteString>
  				for (const key of Object.keys(init)) {
  					const value = init[key];
  					this.append(key, value);
  				}
  			}
  		} else {
  			throw new TypeError('Provided initializer must be an object');
  		}
  	}
  
  	/**
    * Return combined header value given name
    *
    * @param   String  name  Header name
    * @return  Mixed
    */
  	get(name) {
  		name = `${name}`;
  		validateName(name);
  		const key = find(this[MAP], name);
  		if (key === undefined) {
  			return null;
  		}
  
  		return this[MAP][key].join(', ');
  	}
  
  	/**
    * Iterate over all headers
    *
    * @param   Function  callback  Executed for each item with parameters (value, name, thisArg)
    * @param   Boolean   thisArg   `this` context for callback function
    * @return  Void
    */
  	forEach(callback) {
  		let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
  
  		let pairs = getHeaders(this);
  		let i = 0;
  		while (i < pairs.length) {
  			var _pairs$i = pairs[i];
  			const name = _pairs$i[0],
  			      value = _pairs$i[1];
  
  			callback.call(thisArg, value, name, this);
  			pairs = getHeaders(this);
  			i++;
  		}
  	}
  
  	/**
    * Overwrite header values given name
    *
    * @param   String  name   Header name
    * @param   String  value  Header value
    * @return  Void
    */
  	set(name, value) {
  		name = `${name}`;
  		value = `${value}`;
  		validateName(name);
  		validateValue(value);
  		const key = find(this[MAP], name);
  		this[MAP][key !== undefined ? key : name] = [value];
  	}
  
  	/**
    * Append a value onto existing header
    *
    * @param   String  name   Header name
    * @param   String  value  Header value
    * @return  Void
    */
  	append(name, value) {
  		name = `${name}`;
  		value = `${value}`;
  		validateName(name);
  		validateValue(value);
  		const key = find(this[MAP], name);
  		if (key !== undefined) {
  			this[MAP][key].push(value);
  		} else {
  			this[MAP][name] = [value];
  		}
  	}
  
  	/**
    * Check for header name existence
    *
    * @param   String   name  Header name
    * @return  Boolean
    */
  	has(name) {
  		name = `${name}`;
  		validateName(name);
  		return find(this[MAP], name) !== undefined;
  	}
  
  	/**
    * Delete all header values given name
    *
    * @param   String  name  Header name
    * @return  Void
    */
  	delete(name) {
  		name = `${name}`;
  		validateName(name);
  		const key = find(this[MAP], name);
  		if (key !== undefined) {
  			delete this[MAP][key];
  		}
  	}
  
  	/**
    * Return raw headers (non-spec api)
    *
    * @return  Object
    */
  	raw() {
  		return this[MAP];
  	}
  
  	/**
    * Get an iterator on keys.
    *
    * @return  Iterator
    */
  	keys() {
  		return createHeadersIterator(this, 'key');
  	}
  
  	/**
    * Get an iterator on values.
    *
    * @return  Iterator
    */
  	values() {
  		return createHeadersIterator(this, 'value');
  	}
  
  	/**
    * Get an iterator on entries.
    *
    * This is the default iterator of the Headers object.
    *
    * @return  Iterator
    */
  	[Symbol.iterator]() {
  		return createHeadersIterator(this, 'key+value');
  	}
  }
  Headers.prototype.entries = Headers.prototype[Symbol.iterator];
  
  Object.defineProperty(Headers.prototype, Symbol.toStringTag, {
  	value: 'Headers',
  	writable: false,
  	enumerable: false,
  	configurable: true
  });
  
  Object.defineProperties(Headers.prototype, {
  	get: { enumerable: true },
  	forEach: { enumerable: true },
  	set: { enumerable: true },
  	append: { enumerable: true },
  	has: { enumerable: true },
  	delete: { enumerable: true },
  	keys: { enumerable: true },
  	values: { enumerable: true },
  	entries: { enumerable: true }
  });
  
  function getHeaders(headers) {
  	let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';
  
  	const keys = Object.keys(headers[MAP]).sort();
  	return keys.map(kind === 'key' ? function (k) {
  		return k.toLowerCase();
  	} : kind === 'value' ? function (k) {
  		return headers[MAP][k].join(', ');
  	} : function (k) {
  		return [k.toLowerCase(), headers[MAP][k].join(', ')];
  	});
  }
  
  const INTERNAL = Symbol('internal');
  
  function createHeadersIterator(target, kind) {
  	const iterator = Object.create(HeadersIteratorPrototype);
  	iterator[INTERNAL] = {
  		target,
  		kind,
  		index: 0
  	};
  	return iterator;
  }
  
  const HeadersIteratorPrototype = Object.setPrototypeOf({
  	next() {
  		// istanbul ignore if
  		if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {
  			throw new TypeError('Value of `this` is not a HeadersIterator');
  		}
  
  		var _INTERNAL = this[INTERNAL];
  		const target = _INTERNAL.target,
  		      kind = _INTERNAL.kind,
  		      index = _INTERNAL.index;
  
  		const values = getHeaders(target, kind);
  		const len = values.length;
  		if (index >= len) {
  			return {
  				value: undefined,
  				done: true
  			};
  		}
  
  		this[INTERNAL].index = index + 1;
  
  		return {
  			value: values[index],
  			done: false
  		};
  	}
  }, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
  
  Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {
  	value: 'HeadersIterator',
  	writable: false,
  	enumerable: false,
  	configurable: true
  });
  
  /**
   * Export the Headers object in a form that Node.js can consume.
   *
   * @param   Headers  headers
   * @return  Object
   */
  function exportNodeCompatibleHeaders(headers) {
  	const obj = Object.assign({ __proto__: null }, headers[MAP]);
  
  	// http.request() only supports string as Host header. This hack makes
  	// specifying custom Host header possible.
  	const hostHeaderKey = find(headers[MAP], 'Host');
  	if (hostHeaderKey !== undefined) {
  		obj[hostHeaderKey] = obj[hostHeaderKey][0];
  	}
  
  	return obj;
  }
  
  /**
   * Create a Headers object from an object of headers, ignoring those that do
   * not conform to HTTP grammar productions.
   *
   * @param   Object  obj  Object of headers
   * @return  Headers
   */
  function createHeadersLenient(obj) {
  	const headers = new Headers();
  	for (const name of Object.keys(obj)) {
  		if (invalidTokenRegex.test(name)) {
  			continue;
  		}
  		if (Array.isArray(obj[name])) {
  			for (const val of obj[name]) {
  				if (invalidHeaderCharRegex.test(val)) {
  					continue;
  				}
  				if (headers[MAP][name] === undefined) {
  					headers[MAP][name] = [val];
  				} else {
  					headers[MAP][name].push(val);
  				}
  			}
  		} else if (!invalidHeaderCharRegex.test(obj[name])) {
  			headers[MAP][name] = [obj[name]];
  		}
  	}
  	return headers;
  }
  
  const INTERNALS$1 = Symbol('Response internals');
  
  // fix an issue where "STATUS_CODES" aren't a named export for node <10
  const STATUS_CODES = http.STATUS_CODES;
  
  /**
   * Response class
   *
   * @param   Stream  body  Readable stream
   * @param   Object  opts  Response options
   * @return  Void
   */
  class Response$1 {
  	constructor() {
  		let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
  		let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
  		Body.call(this, body, opts);
  
  		const status = opts.status || 200;
  		const headers = new Headers(opts.headers);
  
  		if (body != null && !headers.has('Content-Type')) {
  			const contentType = extractContentType(body);
  			if (contentType) {
  				headers.append('Content-Type', contentType);
  			}
  		}
  
  		this[INTERNALS$1] = {
  			url: opts.url,
  			status,
  			statusText: opts.statusText || STATUS_CODES[status],
  			headers,
  			counter: opts.counter
  		};
  	}
  
  	get url() {
  		return this[INTERNALS$1].url || '';
  	}
  
  	get status() {
  		return this[INTERNALS$1].status;
  	}
  
  	/**
    * Convenience property representing if the request ended normally
    */
  	get ok() {
  		return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;
  	}
  
  	get redirected() {
  		return this[INTERNALS$1].counter > 0;
  	}
  
  	get statusText() {
  		return this[INTERNALS$1].statusText;
  	}
  
  	get headers() {
  		return this[INTERNALS$1].headers;
  	}
  
  	/**
    * Clone this response
    *
    * @return  Response
    */
  	clone() {
  		return new Response$1(clone(this), {
  			url: this.url,
  			status: this.status,
  			statusText: this.statusText,
  			headers: this.headers,
  			ok: this.ok,
  			redirected: this.redirected
  		});
  	}
  }
  
  Body.mixIn(Response$1.prototype);
  
  Object.defineProperties(Response$1.prototype, {
  	url: { enumerable: true },
  	status: { enumerable: true },
  	ok: { enumerable: true },
  	redirected: { enumerable: true },
  	statusText: { enumerable: true },
  	headers: { enumerable: true },
  	clone: { enumerable: true }
  });
  
  Object.defineProperty(Response$1.prototype, Symbol.toStringTag, {
  	value: 'Response',
  	writable: false,
  	enumerable: false,
  	configurable: true
  });
  
  const INTERNALS$2 = Symbol('Request internals');
  
  // fix an issue where "format", "parse" aren't a named export for node <10
  const parse_url = Url.parse;
  const format_url = Url.format;
  
  const streamDestructionSupported = 'destroy' in Stream.Readable.prototype;
  
  /**
   * Check if a value is an instance of Request.
   *
   * @param   Mixed   input
   * @return  Boolean
   */
  function isRequest$2(input) {
  	return typeof input === 'object' && typeof input[INTERNALS$2] === 'object';
  }
  
  function isAbortSignal(signal) {
  	const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal);
  	return !!(proto && proto.constructor.name === 'AbortSignal');
  }
  
  /**
   * Request class
   *
   * @param   Mixed   input  Url or Request instance
   * @param   Object  init   Custom options
   * @return  Void
   */
  class Request {
  	constructor(input) {
  		let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
  		let parsedURL;
  
  		// normalize input
  		if (!isRequest$2(input)) {
  			if (input && input.href) {
  				// in order to support Node.js' Url objects; though WHATWG's URL objects
  				// will fall into this branch also (since their `toString()` will return
  				// `href` property anyway)
  				parsedURL = parse_url(input.href);
  			} else {
  				// coerce input to a string before attempting to parse
  				parsedURL = parse_url(`${input}`);
  			}
  			input = {};
  		} else {
  			parsedURL = parse_url(input.url);
  		}
  
  		let method = init.method || input.method || 'GET';
  		method = method.toUpperCase();
  
  		if ((init.body != null || isRequest$2(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {
  			throw new TypeError('Request with GET/HEAD method cannot have body');
  		}
  
  		let inputBody = init.body != null ? init.body : isRequest$2(input) && input.body !== null ? clone(input) : null;
  
  		Body.call(this, inputBody, {
  			timeout: init.timeout || input.timeout || 0,
  			size: init.size || input.size || 0
  		});
  
  		const headers = new Headers(init.headers || input.headers || {});
  
  		if (inputBody != null && !headers.has('Content-Type')) {
  			const contentType = extractContentType(inputBody);
  			if (contentType) {
  				headers.append('Content-Type', contentType);
  			}
  		}
  
  		let signal = isRequest$2(input) ? input.signal : null;
  		if ('signal' in init) signal = init.signal;
  
  		if (signal != null && !isAbortSignal(signal)) {
  			throw new TypeError('Expected signal to be an instanceof AbortSignal');
  		}
  
  		this[INTERNALS$2] = {
  			method,
  			redirect: init.redirect || input.redirect || 'follow',
  			headers,
  			parsedURL,
  			signal
  		};
  
  		// node-fetch-only options
  		this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
  		this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
  		this.counter = init.counter || input.counter || 0;
  		this.agent = init.agent || input.agent;
  	}
  
  	get method() {
  		return this[INTERNALS$2].method;
  	}
  
  	get url() {
  		return format_url(this[INTERNALS$2].parsedURL);
  	}
  
  	get headers() {
  		return this[INTERNALS$2].headers;
  	}
  
  	get redirect() {
  		return this[INTERNALS$2].redirect;
  	}
  
  	get signal() {
  		return this[INTERNALS$2].signal;
  	}
  
  	/**
    * Clone this request
    *
    * @return  Request
    */
  	clone() {
  		return new Request(this);
  	}
  }
  
  Body.mixIn(Request.prototype);
  
  Object.defineProperty(Request.prototype, Symbol.toStringTag, {
  	value: 'Request',
  	writable: false,
  	enumerable: false,
  	configurable: true
  });
  
  Object.defineProperties(Request.prototype, {
  	method: { enumerable: true },
  	url: { enumerable: true },
  	headers: { enumerable: true },
  	redirect: { enumerable: true },
  	clone: { enumerable: true },
  	signal: { enumerable: true }
  });
  
  /**
   * Convert a Request to Node.js http request options.
   *
   * @param   Request  A Request instance
   * @return  Object   The options object to be passed to http.request
   */
  function getNodeRequestOptions(request) {
  	const parsedURL = request[INTERNALS$2].parsedURL;
  	const headers = new Headers(request[INTERNALS$2].headers);
  
  	// fetch step 1.3
  	if (!headers.has('Accept')) {
  		headers.set('Accept', '*/*');
  	}
  
  	// Basic fetch
  	if (!parsedURL.protocol || !parsedURL.hostname) {
  		throw new TypeError('Only absolute URLs are supported');
  	}
  
  	if (!/^https?:$/.test(parsedURL.protocol)) {
  		throw new TypeError('Only HTTP(S) protocols are supported');
  	}
  
  	if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) {
  		throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8');
  	}
  
  	// HTTP-network-or-cache fetch steps 2.4-2.7
  	let contentLengthValue = null;
  	if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
  		contentLengthValue = '0';
  	}
  	if (request.body != null) {
  		const totalBytes = getTotalBytes(request);
  		if (typeof totalBytes === 'number') {
  			contentLengthValue = String(totalBytes);
  		}
  	}
  	if (contentLengthValue) {
  		headers.set('Content-Length', contentLengthValue);
  	}
  
  	// HTTP-network-or-cache fetch step 2.11
  	if (!headers.has('User-Agent')) {
  		headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');
  	}
  
  	// HTTP-network-or-cache fetch step 2.15
  	if (request.compress && !headers.has('Accept-Encoding')) {
  		headers.set('Accept-Encoding', 'gzip,deflate');
  	}
  
  	let agent = request.agent;
  	if (typeof agent === 'function') {
  		agent = agent(parsedURL);
  	}
  
  	if (!headers.has('Connection') && !agent) {
  		headers.set('Connection', 'close');
  	}
  
  	// HTTP-network fetch step 4.2
  	// chunked encoding is handled by Node.js
  
  	return Object.assign({}, parsedURL, {
  		method: request.method,
  		headers: exportNodeCompatibleHeaders(headers),
  		agent
  	});
  }
  
  /**
   * abort-error.js
   *
   * AbortError interface for cancelled requests
   */
  
  /**
   * Create AbortError instance
   *
   * @param   String      message      Error message for human
   * @return  AbortError
   */
  function AbortError(message) {
    Error.call(this, message);
  
    this.type = 'aborted';
    this.message = message;
  
    // hide custom error implementation details from end-users
    Error.captureStackTrace(this, this.constructor);
  }
  
  AbortError.prototype = Object.create(Error.prototype);
  AbortError.prototype.constructor = AbortError;
  AbortError.prototype.name = 'AbortError';
  
  // fix an issue where "PassThrough", "resolve" aren't a named export for node <10
  const PassThrough$1$1 = Stream.PassThrough;
  const resolve_url = Url.resolve;
  
  /**
   * Fetch function
   *
   * @param   Mixed    url   Absolute url or Request instance
   * @param   Object   opts  Fetch options
   * @return  Promise
   */
  function fetch(url, opts) {
  
  	// allow custom promise
  	if (!fetch.Promise) {
  		throw new Error('native promise missing, set fetch.Promise to your favorite alternative');
  	}
  
  	Body.Promise = fetch.Promise;
  
  	// wrap http.request into fetch
  	return new fetch.Promise(function (resolve, reject) {
  		// build request object
  		const request = new Request(url, opts);
  		const options = getNodeRequestOptions(request);
  
  		const send = (options.protocol === 'https:' ? https : http).request;
  		const signal = request.signal;
  
  		let response = null;
  
  		const abort = function abort() {
  			let error = new AbortError('The user aborted a request.');
  			reject(error);
  			if (request.body && request.body instanceof Stream.Readable) {
  				request.body.destroy(error);
  			}
  			if (!response || !response.body) return;
  			response.body.emit('error', error);
  		};
  
  		if (signal && signal.aborted) {
  			abort();
  			return;
  		}
  
  		const abortAndFinalize = function abortAndFinalize() {
  			abort();
  			finalize();
  		};
  
  		// send request
  		const req = send(options);
  		let reqTimeout;
  
  		if (signal) {
  			signal.addEventListener('abort', abortAndFinalize);
  		}
  
  		function finalize() {
  			req.abort();
  			if (signal) signal.removeEventListener('abort', abortAndFinalize);
  			clearTimeout(reqTimeout);
  		}
  
  		if (request.timeout) {
  			req.once('socket', function (socket) {
  				reqTimeout = setTimeout(function () {
  					reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
  					finalize();
  				}, request.timeout);
  			});
  		}
  
  		req.on('error', function (err) {
  			reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
  			finalize();
  		});
  
  		req.on('response', function (res) {
  			clearTimeout(reqTimeout);
  
  			const headers = createHeadersLenient(res.headers);
  
  			// HTTP fetch step 5
  			if (fetch.isRedirect(res.statusCode)) {
  				// HTTP fetch step 5.2
  				const location = headers.get('Location');
  
  				// HTTP fetch step 5.3
  				const locationURL = location === null ? null : resolve_url(request.url, location);
  
  				// HTTP fetch step 5.5
  				switch (request.redirect) {
  					case 'error':
  						reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));
  						finalize();
  						return;
  					case 'manual':
  						// node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.
  						if (locationURL !== null) {
  							// handle corrupted header
  							try {
  								headers.set('Location', locationURL);
  							} catch (err) {
  								// istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request
  								reject(err);
  							}
  						}
  						break;
  					case 'follow':
  						// HTTP-redirect fetch step 2
  						if (locationURL === null) {
  							break;
  						}
  
  						// HTTP-redirect fetch step 5
  						if (request.counter >= request.follow) {
  							reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
  							finalize();
  							return;
  						}
  
  						// HTTP-redirect fetch step 6 (counter increment)
  						// Create a new Request object.
  						const requestOpts = {
  							headers: new Headers(request.headers),
  							follow: request.follow,
  							counter: request.counter + 1,
  							agent: request.agent,
  							compress: request.compress,
  							method: request.method,
  							body: request.body,
  							signal: request.signal,
  							timeout: request.timeout,
  							size: request.size
  						};
  
  						// HTTP-redirect fetch step 9
  						if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
  							reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
  							finalize();
  							return;
  						}
  
  						// HTTP-redirect fetch step 11
  						if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
  							requestOpts.method = 'GET';
  							requestOpts.body = undefined;
  							requestOpts.headers.delete('content-length');
  						}
  
  						// HTTP-redirect fetch step 15
  						resolve(fetch(new Request(locationURL, requestOpts)));
  						finalize();
  						return;
  				}
  			}
  
  			// prepare response
  			res.once('end', function () {
  				if (signal) signal.removeEventListener('abort', abortAndFinalize);
  			});
  			let body = res.pipe(new PassThrough$1$1());
  
  			const response_options = {
  				url: request.url,
  				status: res.statusCode,
  				statusText: res.statusMessage,
  				headers: headers,
  				size: request.size,
  				timeout: request.timeout,
  				counter: request.counter
  			};
  
  			// HTTP-network fetch step 12.1.1.3
  			const codings = headers.get('Content-Encoding');
  
  			// HTTP-network fetch step 12.1.1.4: handle content codings
  
  			// in following scenarios we ignore compression support
  			// 1. compression support is disabled
  			// 2. HEAD request
  			// 3. no Content-Encoding header
  			// 4. no content response (204)
  			// 5. content not modified response (304)
  			if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {
  				response = new Response$1(body, response_options);
  				resolve(response);
  				return;
  			}
  
  			// For Node v6+
  			// Be less strict when decoding compressed responses, since sometimes
  			// servers send slightly invalid responses that are still accepted
  			// by common browsers.
  			// Always using Z_SYNC_FLUSH is what cURL does.
  			const zlibOptions = {
  				flush: zlib.Z_SYNC_FLUSH,
  				finishFlush: zlib.Z_SYNC_FLUSH
  			};
  
  			// for gzip
  			if (codings == 'gzip' || codings == 'x-gzip') {
  				body = body.pipe(zlib.createGunzip(zlibOptions));
  				response = new Response$1(body, response_options);
  				resolve(response);
  				return;
  			}
  
  			// for deflate
  			if (codings == 'deflate' || codings == 'x-deflate') {
  				// handle the infamous raw deflate response from old servers
  				// a hack for old IIS and Apache servers
  				const raw = res.pipe(new PassThrough$1$1());
  				raw.once('data', function (chunk) {
  					// see http://stackoverflow.com/questions/37519828
  					if ((chunk[0] & 0x0F) === 0x08) {
  						body = body.pipe(zlib.createInflate());
  					} else {
  						body = body.pipe(zlib.createInflateRaw());
  					}
  					response = new Response$1(body, response_options);
  					resolve(response);
  				});
  				return;
  			}
  
  			// for br
  			if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') {
  				body = body.pipe(zlib.createBrotliDecompress());
  				response = new Response$1(body, response_options);
  				resolve(response);
  				return;
  			}
  
  			// otherwise, use response as-is
  			response = new Response$1(body, response_options);
  			resolve(response);
  		});
  
  		writeToStream(req, request);
  	});
  }
  /**
   * Redirect code matching
   *
   * @param   Number   code  Status code
   * @return  Boolean
   */
  fetch.isRedirect = function (code) {
  	return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
  };
  
  // expose Promise
  fetch.Promise = global.Promise;
  
  class Deprecation extends Error {
    constructor(message) {
      super(message); // Maintains proper stack trace (only available on V8)
  
      /* istanbul ignore next */
  
      if (Error.captureStackTrace) {
        Error.captureStackTrace(this, this.constructor);
      }
  
      this.name = 'Deprecation';
    }
  
  }
  
  const logOnce = once_1((deprecation) => console.warn(deprecation));
  /**
   * Error with extra properties to help with debugging
   */
  class RequestError extends Error {
      constructor(message, statusCode, options) {
          super(message);
          // Maintains proper stack trace (only available on V8)
          /* istanbul ignore next */
          if (Error.captureStackTrace) {
              Error.captureStackTrace(this, this.constructor);
          }
          this.name = "HttpError";
          this.status = statusCode;
          Object.defineProperty(this, "code", {
              get() {
                  logOnce(new Deprecation("[@octokit/request-error] `error.code` is deprecated, use `error.status`."));
                  return statusCode;
              },
          });
          this.headers = options.headers || {};
          // redact request credentials without mutating original request options
          const requestCopy = Object.assign({}, options.request);
          if (options.request.headers.authorization) {
              requestCopy.headers = Object.assign({}, options.request.headers, {
                  authorization: options.request.headers.authorization.replace(/ .*$/, " [REDACTED]"),
              });
          }
          requestCopy.url = requestCopy.url
              // client_id & client_secret can be passed as URL query parameters to increase rate limit
              // see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications
              .replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]")
              // OAuth tokens can be passed as URL query parameters, although it is not recommended
              // see https://developer.github.com/v3/#oauth2-token-sent-in-a-header
              .replace(/\baccess_token=\w+/g, "access_token=[REDACTED]");
          this.request = requestCopy;
      }
  }
  
  const VERSION$1 = "5.4.9";
  
  function getBufferResponse(response) {
      return response.arrayBuffer();
  }
  
  function fetchWrapper(requestOptions) {
      if (isPlainObject(requestOptions.body) ||
          Array.isArray(requestOptions.body)) {
          requestOptions.body = JSON.stringify(requestOptions.body);
      }
      let headers = {};
      let status;
      let url;
      const fetch$1 = (requestOptions.request && requestOptions.request.fetch) || fetch;
      return fetch$1(requestOptions.url, Object.assign({
          method: requestOptions.method,
          body: requestOptions.body,
          headers: requestOptions.headers,
          redirect: requestOptions.redirect,
      }, requestOptions.request))
          .then((response) => {
          url = response.url;
          status = response.status;
          for (const keyAndValue of response.headers) {
              headers[keyAndValue[0]] = keyAndValue[1];
          }
          if (status === 204 || status === 205) {
              return;
          }
          // GitHub API returns 200 for HEAD requests
          if (requestOptions.method === "HEAD") {
              if (status < 400) {
                  return;
              }
              throw new RequestError(response.statusText, status, {
                  headers,
                  request: requestOptions,
              });
          }
          if (status === 304) {
              throw new RequestError("Not modified", status, {
                  headers,
                  request: requestOptions,
              });
          }
          if (status >= 400) {
              return response
                  .text()
                  .then((message) => {
                  const error = new RequestError(message, status, {
                      headers,
                      request: requestOptions,
                  });
                  try {
                      let responseBody = JSON.parse(error.message);
                      Object.assign(error, responseBody);
                      let errors = responseBody.errors;
                      // Assumption `errors` would always be in Array format
                      error.message =
                          error.message + ": " + errors.map(JSON.stringify).join(", ");
                  }
                  catch (e) {
                      // ignore, see octokit/rest.js#684
                  }
                  throw error;
              });
          }
          const contentType = response.headers.get("content-type");
          if (/application\/json/.test(contentType)) {
              return response.json();
          }
          if (!contentType || /^text\/|charset=utf-8$/.test(contentType)) {
              return response.text();
          }
          return getBufferResponse(response);
      })
          .then((data) => {
          return {
              status,
              url,
              headers,
              data,
          };
      })
          .catch((error) => {
          if (error instanceof RequestError) {
              throw error;
          }
          throw new RequestError(error.message, 500, {
              headers,
              request: requestOptions,
          });
      });
  }
  
  function withDefaults$1(oldEndpoint, newDefaults) {
      const endpoint = oldEndpoint.defaults(newDefaults);
      const newApi = function (route, parameters) {
          const endpointOptions = endpoint.merge(route, parameters);
          if (!endpointOptions.request || !endpointOptions.request.hook) {
              return fetchWrapper(endpoint.parse(endpointOptions));
          }
          const request = (route, parameters) => {
              return fetchWrapper(endpoint.parse(endpoint.merge(route, parameters)));
          };
          Object.assign(request, {
              endpoint,
              defaults: withDefaults$1.bind(null, endpoint),
          });
          return endpointOptions.request.hook(request, endpointOptions);
      };
      return Object.assign(newApi, {
          endpoint,
          defaults: withDefaults$1.bind(null, endpoint),
      });
  }
  
  const request$1 = withDefaults$1(endpoint, {
      headers: {
          "user-agent": `octokit-request.js/${VERSION$1} ${getUserAgent()}`,
      },
  });
  
  const VERSION$2 = "4.5.6";
  
  class GraphqlError extends Error {
      constructor(request, response) {
          const message = response.data.errors[0].message;
          super(message);
          Object.assign(this, response.data);
          Object.assign(this, { headers: response.headers });
          this.name = "GraphqlError";
          this.request = request;
          // Maintains proper stack trace (only available on V8)
          /* istanbul ignore next */
          if (Error.captureStackTrace) {
              Error.captureStackTrace(this, this.constructor);
          }
      }
  }
  
  const NON_VARIABLE_OPTIONS = [
      "method",
      "baseUrl",
      "url",
      "headers",
      "request",
      "query",
      "mediaType",
  ];
  const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/;
  function graphql(request, query, options) {
      if (typeof query === "string" && options && "query" in options) {
          return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`));
      }
      const parsedOptions = typeof query === "string" ? Object.assign({ query }, options) : query;
      const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {
          if (NON_VARIABLE_OPTIONS.includes(key)) {
              result[key] = parsedOptions[key];
              return result;
          }
          if (!result.variables) {
              result.variables = {};
          }
          result.variables[key] = parsedOptions[key];
          return result;
      }, {});
      // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix
      // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451
      const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;
      if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {
          requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql");
      }
      return request(requestOptions).then((response) => {
          if (response.data.errors) {
              const headers = {};
              for (const key of Object.keys(response.headers)) {
                  headers[key] = response.headers[key];
              }
              throw new GraphqlError(requestOptions, {
                  headers,
                  data: response.data,
              });
          }
          return response.data.data;
      });
  }
  
  function withDefaults$2(request$1$1, newDefaults) {
      const newRequest = request$1$1.defaults(newDefaults);
      const newApi = (query, options) => {
          return graphql(newRequest, query, options);
      };
      return Object.assign(newApi, {
          defaults: withDefaults$2.bind(null, newRequest),
          endpoint: request$1.endpoint,
      });
  }
  
  const graphql$1 = withDefaults$2(request$1, {
      headers: {
          "user-agent": `octokit-graphql.js/${VERSION$2} ${getUserAgent()}`,
      },
      method: "POST",
      url: "/graphql",
  });
  function withCustomRequest(customRequest) {
      return withDefaults$2(customRequest, {
          method: "POST",
          url: "/graphql",
      });
  }
  
  async function auth(token) {
      const tokenType = token.split(/\./).length === 3
          ? "app"
          : /^v\d+\./.test(token)
              ? "installation"
              : "oauth";
      return {
          type: "token",
          token: token,
          tokenType
      };
  }
  
  /**
   * Prefix token for usage in the Authorization header
   *
   * @param token OAuth token or JSON Web Token
   */
  function withAuthorizationPrefix(token) {
      if (token.split(/\./).length === 3) {
          return `bearer ${token}`;
      }
      return `token ${token}`;
  }
  
  async function hook(token, request, route, parameters) {
      const endpoint = request.endpoint.merge(route, parameters);
      endpoint.headers.authorization = withAuthorizationPrefix(token);
      return request(endpoint);
  }
  
  const createTokenAuth = function createTokenAuth(token) {
      if (!token) {
          throw new Error("[@octokit/auth-token] No token passed to createTokenAuth");
      }
      if (typeof token !== "string") {
          throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string");
      }
      token = token.replace(/^(token|bearer) +/i, "");
      return Object.assign(auth.bind(null, token), {
          hook: hook.bind(null, token)
      });
  };
  
  const VERSION$3 = "3.2.1";
  
  class Octokit {
      constructor(options = {}) {
          const hook = new Collection();
          const requestDefaults = {
              baseUrl: request$1.endpoint.DEFAULTS.baseUrl,
              headers: {},
              request: Object.assign({}, options.request, {
                  hook: hook.bind(null, "request"),
              }),
              mediaType: {
                  previews: [],
                  format: "",
              },
          };
          // prepend default user agent with `options.userAgent` if set
          requestDefaults.headers["user-agent"] = [
              options.userAgent,
              `octokit-core.js/${VERSION$3} ${getUserAgent()}`,
          ]
              .filter(Boolean)
              .join(" ");
          if (options.baseUrl) {
              requestDefaults.baseUrl = options.baseUrl;
          }
          if (options.previews) {
              requestDefaults.mediaType.previews = options.previews;
          }
          if (options.timeZone) {
              requestDefaults.headers["time-zone"] = options.timeZone;
          }
          this.request = request$1.defaults(requestDefaults);
          this.graphql = withCustomRequest(this.request).defaults(requestDefaults);
          this.log = Object.assign({
              debug: () => { },
              info: () => { },
              warn: console.warn.bind(console),
              error: console.error.bind(console),
          }, options.log);
          this.hook = hook;
          // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance
          //     is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered.
          // (2) If only `options.auth` is set, use the default token authentication strategy.
          // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance.
          // TODO: type `options.auth` based on `options.authStrategy`.
          if (!options.authStrategy) {
              if (!options.auth) {
                  // (1)
                  this.auth = async () => ({
                      type: "unauthenticated",
                  });
              }
              else {
                  // (2)
                  const auth = createTokenAuth(options.auth);
                  // @ts-ignore  ¯\_(ツ)_/¯
                  hook.wrap("request", auth.hook);
                  this.auth = auth;
              }
          }
          else {
              const { authStrategy, ...otherOptions } = options;
              const auth = authStrategy(Object.assign({
                  request: this.request,
                  log: this.log,
                  // we pass the current octokit instance as well as its constructor options
                  // to allow for authentication strategies that return a new octokit instance
                  // that shares the same internal state as the current one. The original
                  // requirement for this was the "event-octokit" authentication strategy
                  // of https://github.com/probot/octokit-auth-probot.
                  octokit: this,
                  octokitOptions: otherOptions,
              }, options.auth));
              // @ts-ignore  ¯\_(ツ)_/¯
              hook.wrap("request", auth.hook);
              this.auth = auth;
          }
          // apply plugins
          // https://stackoverflow.com/a/16345172
          const classConstructor = this.constructor;
          classConstructor.plugins.forEach((plugin) => {
              Object.assign(this, plugin(this, options));
          });
      }
      static defaults(defaults) {
          const OctokitWithDefaults = class extends this {
              constructor(...args) {
                  const options = args[0] || {};
                  if (typeof defaults === "function") {
                      super(defaults(options));
                      return;
                  }
                  super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent
                      ? {
                          userAgent: `${options.userAgent} ${defaults.userAgent}`,
                      }
                      : null));
              }
          };
          return OctokitWithDefaults;
      }
      /**
       * Attach a plugin (or many) to your Octokit instance.
       *
       * @example
       * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)
       */
      static plugin(...newPlugins) {
          var _a;
          const currentPlugins = this.plugins;
          const NewOctokit = (_a = class extends this {
              },
              _a.plugins = currentPlugins.concat(newPlugins.filter((plugin) => !currentPlugins.includes(plugin))),
              _a);
          return NewOctokit;
      }
  }
  Octokit.VERSION = VERSION$3;
  Octokit.plugins = [];
  
  var distWeb = {
  	__proto__: null,
  	Octokit: Octokit
  };
  
  const Endpoints = {
      actions: {
          addSelectedRepoToOrgSecret: [
              "PUT /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}",
          ],
          cancelWorkflowRun: [
              "POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel",
          ],
          createOrUpdateOrgSecret: ["PUT /orgs/{org}/actions/secrets/{secret_name}"],
          createOrUpdateRepoSecret: [
              "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}",
          ],
          createRegistrationTokenForOrg: [
              "POST /orgs/{org}/actions/runners/registration-token",
          ],
          createRegistrationTokenForRepo: [
              "POST /repos/{owner}/{repo}/actions/runners/registration-token",
          ],
          createRemoveTokenForOrg: ["POST /orgs/{org}/actions/runners/remove-token"],
          createRemoveTokenForRepo: [
              "POST /repos/{owner}/{repo}/actions/runners/remove-token",
          ],
          createWorkflowDispatch: [
              "POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches",
          ],
          deleteArtifact: [
              "DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}",
          ],
          deleteOrgSecret: ["DELETE /orgs/{org}/actions/secrets/{secret_name}"],
          deleteRepoSecret: [
              "DELETE /repos/{owner}/{repo}/actions/secrets/{secret_name}",
          ],
          deleteSelfHostedRunnerFromOrg: [
              "DELETE /orgs/{org}/actions/runners/{runner_id}",
          ],
          deleteSelfHostedRunnerFromRepo: [
              "DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}",
          ],
          deleteWorkflowRun: ["DELETE /repos/{owner}/{repo}/actions/runs/{run_id}"],
          deleteWorkflowRunLogs: [
              "DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs",
          ],
          downloadArtifact: [
              "GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}",
          ],
          downloadJobLogsForWorkflowRun: [
              "GET /repos/{owner}/{repo}/actions/jobs/{job_id}/logs",
          ],
          downloadWorkflowRunLogs: [
              "GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs",
          ],
          getArtifact: ["GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}"],
          getJobForWorkflowRun: ["GET /repos/{owner}/{repo}/actions/jobs/{job_id}"],
          getOrgPublicKey: ["GET /orgs/{org}/actions/secrets/public-key"],
          getOrgSecret: ["GET /orgs/{org}/actions/secrets/{secret_name}"],
          getRepoPublicKey: ["GET /repos/{owner}/{repo}/actions/secrets/public-key"],
          getRepoSecret: ["GET /repos/{owner}/{repo}/actions/secrets/{secret_name}"],
          getSelfHostedRunnerForOrg: ["GET /orgs/{org}/actions/runners/{runner_id}"],
          getSelfHostedRunnerForRepo: [
              "GET /repos/{owner}/{repo}/actions/runners/{runner_id}",
          ],
          getWorkflow: ["GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}"],
          getWorkflowRun: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}"],
          getWorkflowRunUsage: [
              "GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing",
          ],
          getWorkflowUsage: [
              "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing",
          ],
          listArtifactsForRepo: ["GET /repos/{owner}/{repo}/actions/artifacts"],
          listJobsForWorkflowRun: [
              "GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs",
          ],
          listOrgSecrets: ["GET /orgs/{org}/actions/secrets"],
          listRepoSecrets: ["GET /repos/{owner}/{repo}/actions/secrets"],
          listRepoWorkflows: ["GET /repos/{owner}/{repo}/actions/workflows"],
          listRunnerApplicationsForOrg: ["GET /orgs/{org}/actions/runners/downloads"],
          listRunnerApplicationsForRepo: [
              "GET /repos/{owner}/{repo}/actions/runners/downloads",
          ],
          listSelectedReposForOrgSecret: [
              "GET /orgs/{org}/actions/secrets/{secret_name}/repositories",
          ],
          listSelfHostedRunnersForOrg: ["GET /orgs/{org}/actions/runners"],
          listSelfHostedRunnersForRepo: ["GET /repos/{owner}/{repo}/actions/runners"],
          listWorkflowRunArtifacts: [
              "GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts",
          ],
          listWorkflowRuns: [
              "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs",
          ],
          listWorkflowRunsForRepo: ["GET /repos/{owner}/{repo}/actions/runs"],
          reRunWorkflow: ["POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun"],
          removeSelectedRepoFromOrgSecret: [
              "DELETE /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}",
          ],
          setSelectedReposForOrgSecret: [
              "PUT /orgs/{org}/actions/secrets/{secret_name}/repositories",
          ],
      },
      activity: {
          checkRepoIsStarredByAuthenticatedUser: ["GET /user/starred/{owner}/{repo}"],
          deleteRepoSubscription: ["DELETE /repos/{owner}/{repo}/subscription"],
          deleteThreadSubscription: [
              "DELETE /notifications/threads/{thread_id}/subscription",
          ],
          getFeeds: ["GET /feeds"],
          getRepoSubscription: ["GET /repos/{owner}/{repo}/subscription"],
          getThread: ["GET /notifications/threads/{thread_id}"],
          getThreadSubscriptionForAuthenticatedUser: [
              "GET /notifications/threads/{thread_id}/subscription",
          ],
          listEventsForAuthenticatedUser: ["GET /users/{username}/events"],
          listNotificationsForAuthenticatedUser: ["GET /notifications"],
          listOrgEventsForAuthenticatedUser: [
              "GET /users/{username}/events/orgs/{org}",
          ],
          listPublicEvents: ["GET /events"],
          listPublicEventsForRepoNetwork: ["GET /networks/{owner}/{repo}/events"],
          listPublicEventsForUser: ["GET /users/{username}/events/public"],
          listPublicOrgEvents: ["GET /orgs/{org}/events"],
          listReceivedEventsForUser: ["GET /users/{username}/received_events"],
          listReceivedPublicEventsForUser: [
              "GET /users/{username}/received_events/public",
          ],
          listRepoEvents: ["GET /repos/{owner}/{repo}/events"],
          listRepoNotificationsForAuthenticatedUser: [
              "GET /repos/{owner}/{repo}/notifications",
          ],
          listReposStarredByAuthenticatedUser: ["GET /user/starred"],
          listReposStarredByUser: ["GET /users/{username}/starred"],
          listReposWatchedByUser: ["GET /users/{username}/subscriptions"],
          listStargazersForRepo: ["GET /repos/{owner}/{repo}/stargazers"],
          listWatchedReposForAuthenticatedUser: ["GET /user/subscriptions"],
          listWatchersForRepo: ["GET /repos/{owner}/{repo}/subscribers"],
          markNotificationsAsRead: ["PUT /notifications"],
          markRepoNotificationsAsRead: ["PUT /repos/{owner}/{repo}/notifications"],
          markThreadAsRead: ["PATCH /notifications/threads/{thread_id}"],
          setRepoSubscription: ["PUT /repos/{owner}/{repo}/subscription"],
          setThreadSubscription: [
              "PUT /notifications/threads/{thread_id}/subscription",
          ],
          starRepoForAuthenticatedUser: ["PUT /user/starred/{owner}/{repo}"],
          unstarRepoForAuthenticatedUser: ["DELETE /user/starred/{owner}/{repo}"],
      },
      apps: {
          addRepoToInstallation: [
              "PUT /user/installations/{installation_id}/repositories/{repository_id}",
          ],
          checkToken: ["POST /applications/{client_id}/token"],
          createContentAttachment: [
              "POST /content_references/{content_reference_id}/attachments",
              { mediaType: { previews: ["corsair"] } },
          ],
          createFromManifest: ["POST /app-manifests/{code}/conversions"],
          createInstallationAccessToken: [
              "POST /app/installations/{installation_id}/access_tokens",
          ],
          deleteAuthorization: ["DELETE /applications/{client_id}/grant"],
          deleteInstallation: ["DELETE /app/installations/{installation_id}"],
          deleteToken: ["DELETE /applications/{client_id}/token"],
          getAuthenticated: ["GET /app"],
          getBySlug: ["GET /apps/{app_slug}"],
          getInstallation: ["GET /app/installations/{installation_id}"],
          getOrgInstallation: ["GET /orgs/{org}/installation"],
          getRepoInstallation: ["GET /repos/{owner}/{repo}/installation"],
          getSubscriptionPlanForAccount: [
              "GET /marketplace_listing/accounts/{account_id}",
          ],
          getSubscriptionPlanForAccountStubbed: [
              "GET /marketplace_listing/stubbed/accounts/{account_id}",
          ],
          getUserInstallation: ["GET /users/{username}/installation"],
          listAccountsForPlan: ["GET /marketplace_listing/plans/{plan_id}/accounts"],
          listAccountsForPlanStubbed: [
              "GET /marketplace_listing/stubbed/plans/{plan_id}/accounts",
          ],
          listInstallationReposForAuthenticatedUser: [
              "GET /user/installations/{installation_id}/repositories",
          ],
          listInstallations: ["GET /app/installations"],
          listInstallationsForAuthenticatedUser: ["GET /user/installations"],
          listPlans: ["GET /marketplace_listing/plans"],
          listPlansStubbed: ["GET /marketplace_listing/stubbed/plans"],
          listReposAccessibleToInstallation: ["GET /installation/repositories"],
          listSubscriptionsForAuthenticatedUser: ["GET /user/marketplace_purchases"],
          listSubscriptionsForAuthenticatedUserStubbed: [
              "GET /user/marketplace_purchases/stubbed",
          ],
          removeRepoFromInstallation: [
              "DELETE /user/installations/{installation_id}/repositories/{repository_id}",
          ],
          resetToken: ["PATCH /applications/{client_id}/token"],
          revokeInstallationAccessToken: ["DELETE /installation/token"],
          suspendInstallation: ["PUT /app/installations/{installation_id}/suspended"],
          unsuspendInstallation: [
              "DELETE /app/installations/{installation_id}/suspended",
          ],
      },
      billing: {
          getGithubActionsBillingOrg: ["GET /orgs/{org}/settings/billing/actions"],
          getGithubActionsBillingUser: [
              "GET /users/{username}/settings/billing/actions",
          ],
          getGithubPackagesBillingOrg: ["GET /orgs/{org}/settings/billing/packages"],
          getGithubPackagesBillingUser: [
              "GET /users/{username}/settings/billing/packages",
          ],
          getSharedStorageBillingOrg: [
              "GET /orgs/{org}/settings/billing/shared-storage",
          ],
          getSharedStorageBillingUser: [
              "GET /users/{username}/settings/billing/shared-storage",
          ],
      },
      checks: {
          create: [
              "POST /repos/{owner}/{repo}/check-runs",
              { mediaType: { previews: ["antiope"] } },
          ],
          createSuite: [
              "POST /repos/{owner}/{repo}/check-suites",
              { mediaType: { previews: ["antiope"] } },
          ],
          get: [
              "GET /repos/{owner}/{repo}/check-runs/{check_run_id}",
              { mediaType: { previews: ["antiope"] } },
          ],
          getSuite: [
              "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}",
              { mediaType: { previews: ["antiope"] } },
          ],
          listAnnotations: [
              "GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations",
              { mediaType: { previews: ["antiope"] } },
          ],
          listForRef: [
              "GET /repos/{owner}/{repo}/commits/{ref}/check-runs",
              { mediaType: { previews: ["antiope"] } },
          ],
          listForSuite: [
              "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs",
              { mediaType: { previews: ["antiope"] } },
          ],
          listSuitesForRef: [
              "GET /repos/{owner}/{repo}/commits/{ref}/check-suites",
              { mediaType: { previews: ["antiope"] } },
          ],
          rerequestSuite: [
              "POST /repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest",
              { mediaType: { previews: ["antiope"] } },
          ],
          setSuitesPreferences: [
              "PATCH /repos/{owner}/{repo}/check-suites/preferences",
              { mediaType: { previews: ["antiope"] } },
          ],
          update: [
              "PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}",
              { mediaType: { previews: ["antiope"] } },
          ],
      },
      codeScanning: {
          getAlert: [
              "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}",
              {},
              { renamedParameters: { alert_id: "alert_number" } },
          ],
          listAlertsForRepo: ["GET /repos/{owner}/{repo}/code-scanning/alerts"],
          listRecentAnalyses: ["GET /repos/{owner}/{repo}/code-scanning/analyses"],
          updateAlert: [
              "PATCH /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}",
          ],
          uploadSarif: ["POST /repos/{owner}/{repo}/code-scanning/sarifs"],
      },
      codesOfConduct: {
          getAllCodesOfConduct: [
              "GET /codes_of_conduct",
              { mediaType: { previews: ["scarlet-witch"] } },
          ],
          getConductCode: [
              "GET /codes_of_conduct/{key}",
              { mediaType: { previews: ["scarlet-witch"] } },
          ],
          getForRepo: [
              "GET /repos/{owner}/{repo}/community/code_of_conduct",
              { mediaType: { previews: ["scarlet-witch"] } },
          ],
      },
      emojis: { get: ["GET /emojis"] },
      gists: {
          checkIsStarred: ["GET /gists/{gist_id}/star"],
          create: ["POST /gists"],
          createComment: ["POST /gists/{gist_id}/comments"],
          delete: ["DELETE /gists/{gist_id}"],
          deleteComment: ["DELETE /gists/{gist_id}/comments/{comment_id}"],
          fork: ["POST /gists/{gist_id}/forks"],
          get: ["GET /gists/{gist_id}"],
          getComment: ["GET /gists/{gist_id}/comments/{comment_id}"],
          getRevision: ["GET /gists/{gist_id}/{sha}"],
          list: ["GET /gists"],
          listComments: ["GET /gists/{gist_id}/comments"],
          listCommits: ["GET /gists/{gist_id}/commits"],
          listForUser: ["GET /users/{username}/gists"],
          listForks: ["GET /gists/{gist_id}/forks"],
          listPublic: ["GET /gists/public"],
          listStarred: ["GET /gists/starred"],
          star: ["PUT /gists/{gist_id}/star"],
          unstar: ["DELETE /gists/{gist_id}/star"],
          update: ["PATCH /gists/{gist_id}"],
          updateComment: ["PATCH /gists/{gist_id}/comments/{comment_id}"],
      },
      git: {
          createBlob: ["POST /repos/{owner}/{repo}/git/blobs"],
          createCommit: ["POST /repos/{owner}/{repo}/git/commits"],
          createRef: ["POST /repos/{owner}/{repo}/git/refs"],
          createTag: ["POST /repos/{owner}/{repo}/git/tags"],
          createTree: ["POST /repos/{owner}/{repo}/git/trees"],
          deleteRef: ["DELETE /repos/{owner}/{repo}/git/refs/{ref}"],
          getBlob: ["GET /repos/{owner}/{repo}/git/blobs/{file_sha}"],
          getCommit: ["GET /repos/{owner}/{repo}/git/commits/{commit_sha}"],
          getRef: ["GET /repos/{owner}/{repo}/git/ref/{ref}"],
          getTag: ["GET /repos/{owner}/{repo}/git/tags/{tag_sha}"],
          getTree: ["GET /repos/{owner}/{repo}/git/trees/{tree_sha}"],
          listMatchingRefs: ["GET /repos/{owner}/{repo}/git/matching-refs/{ref}"],
          updateRef: ["PATCH /repos/{owner}/{repo}/git/refs/{ref}"],
      },
      gitignore: {
          getAllTemplates: ["GET /gitignore/templates"],
          getTemplate: ["GET /gitignore/templates/{name}"],
      },
      interactions: {
          getRestrictionsForOrg: [
              "GET /orgs/{org}/interaction-limits",
              { mediaType: { previews: ["sombra"] } },
          ],
          getRestrictionsForRepo: [
              "GET /repos/{owner}/{repo}/interaction-limits",
              { mediaType: { previews: ["sombra"] } },
          ],
          removeRestrictionsForOrg: [
              "DELETE /orgs/{org}/interaction-limits",
              { mediaType: { previews: ["sombra"] } },
          ],
          removeRestrictionsForRepo: [
              "DELETE /repos/{owner}/{repo}/interaction-limits",
              { mediaType: { previews: ["sombra"] } },
          ],
          setRestrictionsForOrg: [
              "PUT /orgs/{org}/interaction-limits",
              { mediaType: { previews: ["sombra"] } },
          ],
          setRestrictionsForRepo: [
              "PUT /repos/{owner}/{repo}/interaction-limits",
              { mediaType: { previews: ["sombra"] } },
          ],
      },
      issues: {
          addAssignees: [
              "POST /repos/{owner}/{repo}/issues/{issue_number}/assignees",
          ],
          addLabels: ["POST /repos/{owner}/{repo}/issues/{issue_number}/labels"],
          checkUserCanBeAssigned: ["GET /repos/{owner}/{repo}/assignees/{assignee}"],
          create: ["POST /repos/{owner}/{repo}/issues"],
          createComment: [
              "POST /repos/{owner}/{repo}/issues/{issue_number}/comments",
          ],
          createLabel: ["POST /repos/{owner}/{repo}/labels"],
          createMilestone: ["POST /repos/{owner}/{repo}/milestones"],
          deleteComment: [
              "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}",
          ],
          deleteLabel: ["DELETE /repos/{owner}/{repo}/labels/{name}"],
          deleteMilestone: [
              "DELETE /repos/{owner}/{repo}/milestones/{milestone_number}",
          ],
          get: ["GET /repos/{owner}/{repo}/issues/{issue_number}"],
          getComment: ["GET /repos/{owner}/{repo}/issues/comments/{comment_id}"],
          getEvent: ["GET /repos/{owner}/{repo}/issues/events/{event_id}"],
          getLabel: ["GET /repos/{owner}/{repo}/labels/{name}"],
          getMilestone: ["GET /repos/{owner}/{repo}/milestones/{milestone_number}"],
          list: ["GET /issues"],
          listAssignees: ["GET /repos/{owner}/{repo}/assignees"],
          listComments: ["GET /repos/{owner}/{repo}/issues/{issue_number}/comments"],
          listCommentsForRepo: ["GET /repos/{owner}/{repo}/issues/comments"],
          listEvents: ["GET /repos/{owner}/{repo}/issues/{issue_number}/events"],
          listEventsForRepo: ["GET /repos/{owner}/{repo}/issues/events"],
          listEventsForTimeline: [
              "GET /repos/{owner}/{repo}/issues/{issue_number}/timeline",
              { mediaType: { previews: ["mockingbird"] } },
          ],
          listForAuthenticatedUser: ["GET /user/issues"],
          listForOrg: ["GET /orgs/{org}/issues"],
          listForRepo: ["GET /repos/{owner}/{repo}/issues"],
          listLabelsForMilestone: [
              "GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels",
          ],
          listLabelsForRepo: ["GET /repos/{owner}/{repo}/labels"],
          listLabelsOnIssue: [
              "GET /repos/{owner}/{repo}/issues/{issue_number}/labels",
          ],
          listMilestones: ["GET /repos/{owner}/{repo}/milestones"],
          lock: ["PUT /repos/{owner}/{repo}/issues/{issue_number}/lock"],
          removeAllLabels: [
              "DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels",
          ],
          removeAssignees: [
              "DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees",
          ],
          removeLabel: [
              "DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}",
          ],
          setLabels: ["PUT /repos/{owner}/{repo}/issues/{issue_number}/labels"],
          unlock: ["DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock"],
          update: ["PATCH /repos/{owner}/{repo}/issues/{issue_number}"],
          updateComment: ["PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}"],
          updateLabel: ["PATCH /repos/{owner}/{repo}/labels/{name}"],
          updateMilestone: [
              "PATCH /repos/{owner}/{repo}/milestones/{milestone_number}",
          ],
      },
      licenses: {
          get: ["GET /licenses/{license}"],
          getAllCommonlyUsed: ["GET /licenses"],
          getForRepo: ["GET /repos/{owner}/{repo}/license"],
      },
      markdown: {
          render: ["POST /markdown"],
          renderRaw: [
              "POST /markdown/raw",
              { headers: { "content-type": "text/plain; charset=utf-8" } },
          ],
      },
      meta: { get: ["GET /meta"] },
      migrations: {
          cancelImport: ["DELETE /repos/{owner}/{repo}/import"],
          deleteArchiveForAuthenticatedUser: [
              "DELETE /user/migrations/{migration_id}/archive",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          deleteArchiveForOrg: [
              "DELETE /orgs/{org}/migrations/{migration_id}/archive",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          downloadArchiveForOrg: [
              "GET /orgs/{org}/migrations/{migration_id}/archive",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          getArchiveForAuthenticatedUser: [
              "GET /user/migrations/{migration_id}/archive",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          getCommitAuthors: ["GET /repos/{owner}/{repo}/import/authors"],
          getImportStatus: ["GET /repos/{owner}/{repo}/import"],
          getLargeFiles: ["GET /repos/{owner}/{repo}/import/large_files"],
          getStatusForAuthenticatedUser: [
              "GET /user/migrations/{migration_id}",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          getStatusForOrg: [
              "GET /orgs/{org}/migrations/{migration_id}",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          listForAuthenticatedUser: [
              "GET /user/migrations",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          listForOrg: [
              "GET /orgs/{org}/migrations",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          listReposForOrg: [
              "GET /orgs/{org}/migrations/{migration_id}/repositories",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          listReposForUser: [
              "GET /user/migrations/{migration_id}/repositories",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          mapCommitAuthor: ["PATCH /repos/{owner}/{repo}/import/authors/{author_id}"],
          setLfsPreference: ["PATCH /repos/{owner}/{repo}/import/lfs"],
          startForAuthenticatedUser: ["POST /user/migrations"],
          startForOrg: ["POST /orgs/{org}/migrations"],
          startImport: ["PUT /repos/{owner}/{repo}/import"],
          unlockRepoForAuthenticatedUser: [
              "DELETE /user/migrations/{migration_id}/repos/{repo_name}/lock",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          unlockRepoForOrg: [
              "DELETE /orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock",
              { mediaType: { previews: ["wyandotte"] } },
          ],
          updateImport: ["PATCH /repos/{owner}/{repo}/import"],
      },
      orgs: {
          blockUser: ["PUT /orgs/{org}/blocks/{username}"],
          checkBlockedUser: ["GET /orgs/{org}/blocks/{username}"],
          checkMembershipForUser: ["GET /orgs/{org}/members/{username}"],
          checkPublicMembershipForUser: ["GET /orgs/{org}/public_members/{username}"],
          convertMemberToOutsideCollaborator: [
              "PUT /orgs/{org}/outside_collaborators/{username}",
          ],
          createInvitation: ["POST /orgs/{org}/invitations"],
          createWebhook: ["POST /orgs/{org}/hooks"],
          deleteWebhook: ["DELETE /orgs/{org}/hooks/{hook_id}"],
          get: ["GET /orgs/{org}"],
          getMembershipForAuthenticatedUser: ["GET /user/memberships/orgs/{org}"],
          getMembershipForUser: ["GET /orgs/{org}/memberships/{username}"],
          getWebhook: ["GET /orgs/{org}/hooks/{hook_id}"],
          list: ["GET /organizations"],
          listAppInstallations: ["GET /orgs/{org}/installations"],
          listBlockedUsers: ["GET /orgs/{org}/blocks"],
          listForAuthenticatedUser: ["GET /user/orgs"],
          listForUser: ["GET /users/{username}/orgs"],
          listInvitationTeams: ["GET /orgs/{org}/invitations/{invitation_id}/teams"],
          listMembers: ["GET /orgs/{org}/members"],
          listMembershipsForAuthenticatedUser: ["GET /user/memberships/orgs"],
          listOutsideCollaborators: ["GET /orgs/{org}/outside_collaborators"],
          listPendingInvitations: ["GET /orgs/{org}/invitations"],
          listPublicMembers: ["GET /orgs/{org}/public_members"],
          listWebhooks: ["GET /orgs/{org}/hooks"],
          pingWebhook: ["POST /orgs/{org}/hooks/{hook_id}/pings"],
          removeMember: ["DELETE /orgs/{org}/members/{username}"],
          removeMembershipForUser: ["DELETE /orgs/{org}/memberships/{username}"],
          removeOutsideCollaborator: [
              "DELETE /orgs/{org}/outside_collaborators/{username}",
          ],
          removePublicMembershipForAuthenticatedUser: [
              "DELETE /orgs/{org}/public_members/{username}",
          ],
          setMembershipForUser: ["PUT /orgs/{org}/memberships/{username}"],
          setPublicMembershipForAuthenticatedUser: [
              "PUT /orgs/{org}/public_members/{username}",
          ],
          unblockUser: ["DELETE /orgs/{org}/blocks/{username}"],
          update: ["PATCH /orgs/{org}"],
          updateMembershipForAuthenticatedUser: [
              "PATCH /user/memberships/orgs/{org}",
          ],
          updateWebhook: ["PATCH /orgs/{org}/hooks/{hook_id}"],
      },
      projects: {
          addCollaborator: [
              "PUT /projects/{project_id}/collaborators/{username}",
              { mediaType: { previews: ["inertia"] } },
          ],
          createCard: [
              "POST /projects/columns/{column_id}/cards",
              { mediaType: { previews: ["inertia"] } },
          ],
          createColumn: [
              "POST /projects/{project_id}/columns",
              { mediaType: { previews: ["inertia"] } },
          ],
          createForAuthenticatedUser: [
              "POST /user/projects",
              { mediaType: { previews: ["inertia"] } },
          ],
          createForOrg: [
              "POST /orgs/{org}/projects",
              { mediaType: { previews: ["inertia"] } },
          ],
          createForRepo: [
              "POST /repos/{owner}/{repo}/projects",
              { mediaType: { previews: ["inertia"] } },
          ],
          delete: [
              "DELETE /projects/{project_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          deleteCard: [
              "DELETE /projects/columns/cards/{card_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          deleteColumn: [
              "DELETE /projects/columns/{column_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          get: [
              "GET /projects/{project_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          getCard: [
              "GET /projects/columns/cards/{card_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          getColumn: [
              "GET /projects/columns/{column_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          getPermissionForUser: [
              "GET /projects/{project_id}/collaborators/{username}/permission",
              { mediaType: { previews: ["inertia"] } },
          ],
          listCards: [
              "GET /projects/columns/{column_id}/cards",
              { mediaType: { previews: ["inertia"] } },
          ],
          listCollaborators: [
              "GET /projects/{project_id}/collaborators",
              { mediaType: { previews: ["inertia"] } },
          ],
          listColumns: [
              "GET /projects/{project_id}/columns",
              { mediaType: { previews: ["inertia"] } },
          ],
          listForOrg: [
              "GET /orgs/{org}/projects",
              { mediaType: { previews: ["inertia"] } },
          ],
          listForRepo: [
              "GET /repos/{owner}/{repo}/projects",
              { mediaType: { previews: ["inertia"] } },
          ],
          listForUser: [
              "GET /users/{username}/projects",
              { mediaType: { previews: ["inertia"] } },
          ],
          moveCard: [
              "POST /projects/columns/cards/{card_id}/moves",
              { mediaType: { previews: ["inertia"] } },
          ],
          moveColumn: [
              "POST /projects/columns/{column_id}/moves",
              { mediaType: { previews: ["inertia"] } },
          ],
          removeCollaborator: [
              "DELETE /projects/{project_id}/collaborators/{username}",
              { mediaType: { previews: ["inertia"] } },
          ],
          update: [
              "PATCH /projects/{project_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          updateCard: [
              "PATCH /projects/columns/cards/{card_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          updateColumn: [
              "PATCH /projects/columns/{column_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
      },
      pulls: {
          checkIfMerged: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/merge"],
          create: ["POST /repos/{owner}/{repo}/pulls"],
          createReplyForReviewComment: [
              "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies",
          ],
          createReview: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews"],
          createReviewComment: [
              "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments",
          ],
          deletePendingReview: [
              "DELETE /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}",
          ],
          deleteReviewComment: [
              "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}",
          ],
          dismissReview: [
              "PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals",
          ],
          get: ["GET /repos/{owner}/{repo}/pulls/{pull_number}"],
          getReview: [
              "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}",
          ],
          getReviewComment: ["GET /repos/{owner}/{repo}/pulls/comments/{comment_id}"],
          list: ["GET /repos/{owner}/{repo}/pulls"],
          listCommentsForReview: [
              "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments",
          ],
          listCommits: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/commits"],
          listFiles: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/files"],
          listRequestedReviewers: [
              "GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers",
          ],
          listReviewComments: [
              "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments",
          ],
          listReviewCommentsForRepo: ["GET /repos/{owner}/{repo}/pulls/comments"],
          listReviews: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews"],
          merge: ["PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge"],
          removeRequestedReviewers: [
              "DELETE /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers",
          ],
          requestReviewers: [
              "POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers",
          ],
          submitReview: [
              "POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events",
          ],
          update: ["PATCH /repos/{owner}/{repo}/pulls/{pull_number}"],
          updateBranch: [
              "PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch",
              { mediaType: { previews: ["lydian"] } },
          ],
          updateReview: [
              "PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}",
          ],
          updateReviewComment: [
              "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}",
          ],
      },
      rateLimit: { get: ["GET /rate_limit"] },
      reactions: {
          createForCommitComment: [
              "POST /repos/{owner}/{repo}/comments/{comment_id}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          createForIssue: [
              "POST /repos/{owner}/{repo}/issues/{issue_number}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          createForIssueComment: [
              "POST /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          createForPullRequestReviewComment: [
              "POST /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          createForTeamDiscussionCommentInOrg: [
              "POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          createForTeamDiscussionInOrg: [
              "POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          deleteForCommitComment: [
              "DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          deleteForIssue: [
              "DELETE /repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          deleteForIssueComment: [
              "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          deleteForPullRequestComment: [
              "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          deleteForTeamDiscussion: [
              "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions/{reaction_id}",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          deleteForTeamDiscussionComment: [
              "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions/{reaction_id}",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          deleteLegacy: [
              "DELETE /reactions/{reaction_id}",
              { mediaType: { previews: ["squirrel-girl"] } },
              {
                  deprecated: "octokit.reactions.deleteLegacy() is deprecated, see https://developer.github.com/v3/reactions/#delete-a-reaction-legacy",
              },
          ],
          listForCommitComment: [
              "GET /repos/{owner}/{repo}/comments/{comment_id}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          listForIssue: [
              "GET /repos/{owner}/{repo}/issues/{issue_number}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          listForIssueComment: [
              "GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          listForPullRequestReviewComment: [
              "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          listForTeamDiscussionCommentInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
          listForTeamDiscussionInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions",
              { mediaType: { previews: ["squirrel-girl"] } },
          ],
      },
      repos: {
          acceptInvitation: ["PATCH /user/repository_invitations/{invitation_id}"],
          addAppAccessRestrictions: [
              "POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps",
              {},
              { mapToData: "apps" },
          ],
          addCollaborator: ["PUT /repos/{owner}/{repo}/collaborators/{username}"],
          addStatusCheckContexts: [
              "POST /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts",
              {},
              { mapToData: "contexts" },
          ],
          addTeamAccessRestrictions: [
              "POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams",
              {},
              { mapToData: "teams" },
          ],
          addUserAccessRestrictions: [
              "POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users",
              {},
              { mapToData: "users" },
          ],
          checkCollaborator: ["GET /repos/{owner}/{repo}/collaborators/{username}"],
          checkVulnerabilityAlerts: [
              "GET /repos/{owner}/{repo}/vulnerability-alerts",
              { mediaType: { previews: ["dorian"] } },
          ],
          compareCommits: ["GET /repos/{owner}/{repo}/compare/{base}...{head}"],
          createCommitComment: [
              "POST /repos/{owner}/{repo}/commits/{commit_sha}/comments",
          ],
          createCommitSignatureProtection: [
              "POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures",
              { mediaType: { previews: ["zzzax"] } },
          ],
          createCommitStatus: ["POST /repos/{owner}/{repo}/statuses/{sha}"],
          createDeployKey: ["POST /repos/{owner}/{repo}/keys"],
          createDeployment: ["POST /repos/{owner}/{repo}/deployments"],
          createDeploymentStatus: [
              "POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses",
          ],
          createDispatchEvent: ["POST /repos/{owner}/{repo}/dispatches"],
          createForAuthenticatedUser: ["POST /user/repos"],
          createFork: ["POST /repos/{owner}/{repo}/forks"],
          createInOrg: ["POST /orgs/{org}/repos"],
          createOrUpdateFileContents: ["PUT /repos/{owner}/{repo}/contents/{path}"],
          createPagesSite: [
              "POST /repos/{owner}/{repo}/pages",
              { mediaType: { previews: ["switcheroo"] } },
          ],
          createRelease: ["POST /repos/{owner}/{repo}/releases"],
          createUsingTemplate: [
              "POST /repos/{template_owner}/{template_repo}/generate",
              { mediaType: { previews: ["baptiste"] } },
          ],
          createWebhook: ["POST /repos/{owner}/{repo}/hooks"],
          declineInvitation: ["DELETE /user/repository_invitations/{invitation_id}"],
          delete: ["DELETE /repos/{owner}/{repo}"],
          deleteAccessRestrictions: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions",
          ],
          deleteAdminBranchProtection: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins",
          ],
          deleteBranchProtection: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection",
          ],
          deleteCommitComment: ["DELETE /repos/{owner}/{repo}/comments/{comment_id}"],
          deleteCommitSignatureProtection: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures",
              { mediaType: { previews: ["zzzax"] } },
          ],
          deleteDeployKey: ["DELETE /repos/{owner}/{repo}/keys/{key_id}"],
          deleteDeployment: [
              "DELETE /repos/{owner}/{repo}/deployments/{deployment_id}",
          ],
          deleteFile: ["DELETE /repos/{owner}/{repo}/contents/{path}"],
          deleteInvitation: [
              "DELETE /repos/{owner}/{repo}/invitations/{invitation_id}",
          ],
          deletePagesSite: [
              "DELETE /repos/{owner}/{repo}/pages",
              { mediaType: { previews: ["switcheroo"] } },
          ],
          deletePullRequestReviewProtection: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews",
          ],
          deleteRelease: ["DELETE /repos/{owner}/{repo}/releases/{release_id}"],
          deleteReleaseAsset: [
              "DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}",
          ],
          deleteWebhook: ["DELETE /repos/{owner}/{repo}/hooks/{hook_id}"],
          disableAutomatedSecurityFixes: [
              "DELETE /repos/{owner}/{repo}/automated-security-fixes",
              { mediaType: { previews: ["london"] } },
          ],
          disableVulnerabilityAlerts: [
              "DELETE /repos/{owner}/{repo}/vulnerability-alerts",
              { mediaType: { previews: ["dorian"] } },
          ],
          downloadArchive: ["GET /repos/{owner}/{repo}/{archive_format}/{ref}"],
          enableAutomatedSecurityFixes: [
              "PUT /repos/{owner}/{repo}/automated-security-fixes",
              { mediaType: { previews: ["london"] } },
          ],
          enableVulnerabilityAlerts: [
              "PUT /repos/{owner}/{repo}/vulnerability-alerts",
              { mediaType: { previews: ["dorian"] } },
          ],
          get: ["GET /repos/{owner}/{repo}"],
          getAccessRestrictions: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions",
          ],
          getAdminBranchProtection: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins",
          ],
          getAllStatusCheckContexts: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts",
          ],
          getAllTopics: [
              "GET /repos/{owner}/{repo}/topics",
              { mediaType: { previews: ["mercy"] } },
          ],
          getAppsWithAccessToProtectedBranch: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps",
          ],
          getBranch: ["GET /repos/{owner}/{repo}/branches/{branch}"],
          getBranchProtection: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection",
          ],
          getClones: ["GET /repos/{owner}/{repo}/traffic/clones"],
          getCodeFrequencyStats: ["GET /repos/{owner}/{repo}/stats/code_frequency"],
          getCollaboratorPermissionLevel: [
              "GET /repos/{owner}/{repo}/collaborators/{username}/permission",
          ],
          getCombinedStatusForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/status"],
          getCommit: ["GET /repos/{owner}/{repo}/commits/{ref}"],
          getCommitActivityStats: ["GET /repos/{owner}/{repo}/stats/commit_activity"],
          getCommitComment: ["GET /repos/{owner}/{repo}/comments/{comment_id}"],
          getCommitSignatureProtection: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures",
              { mediaType: { previews: ["zzzax"] } },
          ],
          getCommunityProfileMetrics: [
              "GET /repos/{owner}/{repo}/community/profile",
              { mediaType: { previews: ["black-panther"] } },
          ],
          getContent: ["GET /repos/{owner}/{repo}/contents/{path}"],
          getContributorsStats: ["GET /repos/{owner}/{repo}/stats/contributors"],
          getDeployKey: ["GET /repos/{owner}/{repo}/keys/{key_id}"],
          getDeployment: ["GET /repos/{owner}/{repo}/deployments/{deployment_id}"],
          getDeploymentStatus: [
              "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}",
          ],
          getLatestPagesBuild: ["GET /repos/{owner}/{repo}/pages/builds/latest"],
          getLatestRelease: ["GET /repos/{owner}/{repo}/releases/latest"],
          getPages: ["GET /repos/{owner}/{repo}/pages"],
          getPagesBuild: ["GET /repos/{owner}/{repo}/pages/builds/{build_id}"],
          getParticipationStats: ["GET /repos/{owner}/{repo}/stats/participation"],
          getPullRequestReviewProtection: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews",
          ],
          getPunchCardStats: ["GET /repos/{owner}/{repo}/stats/punch_card"],
          getReadme: ["GET /repos/{owner}/{repo}/readme"],
          getRelease: ["GET /repos/{owner}/{repo}/releases/{release_id}"],
          getReleaseAsset: ["GET /repos/{owner}/{repo}/releases/assets/{asset_id}"],
          getReleaseByTag: ["GET /repos/{owner}/{repo}/releases/tags/{tag}"],
          getStatusChecksProtection: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks",
          ],
          getTeamsWithAccessToProtectedBranch: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams",
          ],
          getTopPaths: ["GET /repos/{owner}/{repo}/traffic/popular/paths"],
          getTopReferrers: ["GET /repos/{owner}/{repo}/traffic/popular/referrers"],
          getUsersWithAccessToProtectedBranch: [
              "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users",
          ],
          getViews: ["GET /repos/{owner}/{repo}/traffic/views"],
          getWebhook: ["GET /repos/{owner}/{repo}/hooks/{hook_id}"],
          listBranches: ["GET /repos/{owner}/{repo}/branches"],
          listBranchesForHeadCommit: [
              "GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head",
              { mediaType: { previews: ["groot"] } },
          ],
          listCollaborators: ["GET /repos/{owner}/{repo}/collaborators"],
          listCommentsForCommit: [
              "GET /repos/{owner}/{repo}/commits/{commit_sha}/comments",
          ],
          listCommitCommentsForRepo: ["GET /repos/{owner}/{repo}/comments"],
          listCommitStatusesForRef: [
              "GET /repos/{owner}/{repo}/commits/{ref}/statuses",
          ],
          listCommits: ["GET /repos/{owner}/{repo}/commits"],
          listContributors: ["GET /repos/{owner}/{repo}/contributors"],
          listDeployKeys: ["GET /repos/{owner}/{repo}/keys"],
          listDeploymentStatuses: [
              "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses",
          ],
          listDeployments: ["GET /repos/{owner}/{repo}/deployments"],
          listForAuthenticatedUser: ["GET /user/repos"],
          listForOrg: ["GET /orgs/{org}/repos"],
          listForUser: ["GET /users/{username}/repos"],
          listForks: ["GET /repos/{owner}/{repo}/forks"],
          listInvitations: ["GET /repos/{owner}/{repo}/invitations"],
          listInvitationsForAuthenticatedUser: ["GET /user/repository_invitations"],
          listLanguages: ["GET /repos/{owner}/{repo}/languages"],
          listPagesBuilds: ["GET /repos/{owner}/{repo}/pages/builds"],
          listPublic: ["GET /repositories"],
          listPullRequestsAssociatedWithCommit: [
              "GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls",
              { mediaType: { previews: ["groot"] } },
          ],
          listReleaseAssets: [
              "GET /repos/{owner}/{repo}/releases/{release_id}/assets",
          ],
          listReleases: ["GET /repos/{owner}/{repo}/releases"],
          listTags: ["GET /repos/{owner}/{repo}/tags"],
          listTeams: ["GET /repos/{owner}/{repo}/teams"],
          listWebhooks: ["GET /repos/{owner}/{repo}/hooks"],
          merge: ["POST /repos/{owner}/{repo}/merges"],
          pingWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/pings"],
          removeAppAccessRestrictions: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps",
              {},
              { mapToData: "apps" },
          ],
          removeCollaborator: [
              "DELETE /repos/{owner}/{repo}/collaborators/{username}",
          ],
          removeStatusCheckContexts: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts",
              {},
              { mapToData: "contexts" },
          ],
          removeStatusCheckProtection: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks",
          ],
          removeTeamAccessRestrictions: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams",
              {},
              { mapToData: "teams" },
          ],
          removeUserAccessRestrictions: [
              "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users",
              {},
              { mapToData: "users" },
          ],
          replaceAllTopics: [
              "PUT /repos/{owner}/{repo}/topics",
              { mediaType: { previews: ["mercy"] } },
          ],
          requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"],
          setAdminBranchProtection: [
              "POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins",
          ],
          setAppAccessRestrictions: [
              "PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps",
              {},
              { mapToData: "apps" },
          ],
          setStatusCheckContexts: [
              "PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts",
              {},
              { mapToData: "contexts" },
          ],
          setTeamAccessRestrictions: [
              "PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams",
              {},
              { mapToData: "teams" },
          ],
          setUserAccessRestrictions: [
              "PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users",
              {},
              { mapToData: "users" },
          ],
          testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"],
          transfer: ["POST /repos/{owner}/{repo}/transfer"],
          update: ["PATCH /repos/{owner}/{repo}"],
          updateBranchProtection: [
              "PUT /repos/{owner}/{repo}/branches/{branch}/protection",
          ],
          updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"],
          updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"],
          updateInvitation: [
              "PATCH /repos/{owner}/{repo}/invitations/{invitation_id}",
          ],
          updatePullRequestReviewProtection: [
              "PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews",
          ],
          updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"],
          updateReleaseAsset: [
              "PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}",
          ],
          updateStatusCheckPotection: [
              "PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks",
          ],
          updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"],
          uploadReleaseAsset: [
              "POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}",
              { baseUrl: "https://uploads.github.com" },
          ],
      },
      search: {
          code: ["GET /search/code"],
          commits: ["GET /search/commits", { mediaType: { previews: ["cloak"] } }],
          issuesAndPullRequests: ["GET /search/issues"],
          labels: ["GET /search/labels"],
          repos: ["GET /search/repositories"],
          topics: ["GET /search/topics", { mediaType: { previews: ["mercy"] } }],
          users: ["GET /search/users"],
      },
      teams: {
          addOrUpdateMembershipForUserInOrg: [
              "PUT /orgs/{org}/teams/{team_slug}/memberships/{username}",
          ],
          addOrUpdateProjectPermissionsInOrg: [
              "PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          addOrUpdateRepoPermissionsInOrg: [
              "PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}",
          ],
          checkPermissionsForProjectInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/projects/{project_id}",
              { mediaType: { previews: ["inertia"] } },
          ],
          checkPermissionsForRepoInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}",
          ],
          create: ["POST /orgs/{org}/teams"],
          createDiscussionCommentInOrg: [
              "POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments",
          ],
          createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"],
          deleteDiscussionCommentInOrg: [
              "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}",
          ],
          deleteDiscussionInOrg: [
              "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}",
          ],
          deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"],
          getByName: ["GET /orgs/{org}/teams/{team_slug}"],
          getDiscussionCommentInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}",
          ],
          getDiscussionInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}",
          ],
          getMembershipForUserInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/memberships/{username}",
          ],
          list: ["GET /orgs/{org}/teams"],
          listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"],
          listDiscussionCommentsInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments",
          ],
          listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"],
          listForAuthenticatedUser: ["GET /user/teams"],
          listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"],
          listPendingInvitationsInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/invitations",
          ],
          listProjectsInOrg: [
              "GET /orgs/{org}/teams/{team_slug}/projects",
              { mediaType: { previews: ["inertia"] } },
          ],
          listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"],
          removeMembershipForUserInOrg: [
              "DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}",
          ],
          removeProjectInOrg: [
              "DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}",
          ],
          removeRepoInOrg: [
              "DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}",
          ],
          updateDiscussionCommentInOrg: [
              "PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}",
          ],
          updateDiscussionInOrg: [
              "PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}",
          ],
          updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"],
      },
      users: {
          addEmailForAuthenticated: ["POST /user/emails"],
          block: ["PUT /user/blocks/{username}"],
          checkBlocked: ["GET /user/blocks/{username}"],
          checkFollowingForUser: ["GET /users/{username}/following/{target_user}"],
          checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"],
          createGpgKeyForAuthenticated: ["POST /user/gpg_keys"],
          createPublicSshKeyForAuthenticated: ["POST /user/keys"],
          deleteEmailForAuthenticated: ["DELETE /user/emails"],
          deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}"],
          deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}"],
          follow: ["PUT /user/following/{username}"],
          getAuthenticated: ["GET /user"],
          getByUsername: ["GET /users/{username}"],
          getContextForUser: ["GET /users/{username}/hovercard"],
          getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}"],
          getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}"],
          list: ["GET /users"],
          listBlockedByAuthenticated: ["GET /user/blocks"],
          listEmailsForAuthenticated: ["GET /user/emails"],
          listFollowedByAuthenticated: ["GET /user/following"],
          listFollowersForAuthenticatedUser: ["GET /user/followers"],
          listFollowersForUser: ["GET /users/{username}/followers"],
          listFollowingForUser: ["GET /users/{username}/following"],
          listGpgKeysForAuthenticated: ["GET /user/gpg_keys"],
          listGpgKeysForUser: ["GET /users/{username}/gpg_keys"],
          listPublicEmailsForAuthenticated: ["GET /user/public_emails"],
          listPublicKeysForUser: ["GET /users/{username}/keys"],
          listPublicSshKeysForAuthenticated: ["GET /user/keys"],
          setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility"],
          unblock: ["DELETE /user/blocks/{username}"],
          unfollow: ["DELETE /user/following/{username}"],
          updateAuthenticated: ["PATCH /user"],
      },
  };
  
  const VERSION$4 = "4.2.0";
  
  function endpointsToMethods(octokit, endpointsMap) {
      const newMethods = {};
      for (const [scope, endpoints] of Object.entries(endpointsMap)) {
          for (const [methodName, endpoint] of Object.entries(endpoints)) {
              const [route, defaults, decorations] = endpoint;
              const [method, url] = route.split(/ /);
              const endpointDefaults = Object.assign({ method, url }, defaults);
              if (!newMethods[scope]) {
                  newMethods[scope] = {};
              }
              const scopeMethods = newMethods[scope];
              if (decorations) {
                  scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations);
                  continue;
              }
              scopeMethods[methodName] = octokit.request.defaults(endpointDefaults);
          }
      }
      return newMethods;
  }
  function decorate(octokit, scope, methodName, defaults, decorations) {
      const requestWithDefaults = octokit.request.defaults(defaults);
      /* istanbul ignore next */
      function withDecorations(...args) {
          // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488
          let options = requestWithDefaults.endpoint.merge(...args);
          // There are currently no other decorations than `.mapToData`
          if (decorations.mapToData) {
              options = Object.assign({}, options, {
                  data: options[decorations.mapToData],
                  [decorations.mapToData]: undefined,
              });
              return requestWithDefaults(options);
          }
          if (decorations.renamed) {
              const [newScope, newMethodName] = decorations.renamed;
              octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`);
          }
          if (decorations.deprecated) {
              octokit.log.warn(decorations.deprecated);
          }
          if (decorations.renamedParameters) {
              // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488
              const options = requestWithDefaults.endpoint.merge(...args);
              for (const [name, alias] of Object.entries(decorations.renamedParameters)) {
                  if (name in options) {
                      octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`);
                      if (!(alias in options)) {
                          options[alias] = options[name];
                      }
                      delete options[name];
                  }
              }
              return requestWithDefaults(options);
          }
          // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488
          return requestWithDefaults(...args);
      }
      return Object.assign(withDecorations, requestWithDefaults);
  }
  
  /**
   * This plugin is a 1:1 copy of internal @octokit/rest plugins. The primary
   * goal is to rebuild @octokit/rest on top of @octokit/core. Once that is
   * done, we will remove the registerEndpoints methods and return the methods
   * directly as with the other plugins. At that point we will also remove the
   * legacy workarounds and deprecations.
   *
   * See the plan at
   * https://github.com/octokit/plugin-rest-endpoint-methods.js/pull/1
   */
  function restEndpointMethods(octokit) {
      return endpointsToMethods(octokit, Endpoints);
  }
  restEndpointMethods.VERSION = VERSION$4;
  
  var distWeb$1 = {
  	__proto__: null,
  	restEndpointMethods: restEndpointMethods
  };
  
  const VERSION$5 = "2.5.0";
  
  /**
   * Some “list” response that can be paginated have a different response structure
   *
   * They have a `total_count` key in the response (search also has `incomplete_results`,
   * /installation/repositories also has `repository_selection`), as well as a key with
   * the list of the items which name varies from endpoint to endpoint.
   *
   * Octokit normalizes these responses so that paginated results are always returned following
   * the same structure. One challenge is that if the list response has only one page, no Link
   * header is provided, so this header alone is not sufficient to check wether a response is
   * paginated or not.
   *
   * We check if a "total_count" key is present in the response data, but also make sure that
   * a "url" property is not, as the "Get the combined status for a specific ref" endpoint would
   * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
   */
  function normalizePaginatedListResponse(response) {
      const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data);
      if (!responseNeedsNormalization)
          return response;
      // keep the additional properties intact as there is currently no other way
      // to retrieve the same information.
      const incompleteResults = response.data.incomplete_results;
      const repositorySelection = response.data.repository_selection;
      const totalCount = response.data.total_count;
      delete response.data.incomplete_results;
      delete response.data.repository_selection;
      delete response.data.total_count;
      const namespaceKey = Object.keys(response.data)[0];
      const data = response.data[namespaceKey];
      response.data = data;
      if (typeof incompleteResults !== "undefined") {
          response.data.incomplete_results = incompleteResults;
      }
      if (typeof repositorySelection !== "undefined") {
          response.data.repository_selection = repositorySelection;
      }
      response.data.total_count = totalCount;
      return response;
  }
  
  function iterator(octokit, route, parameters) {
      const options = typeof route === "function"
          ? route.endpoint(parameters)
          : octokit.request.endpoint(route, parameters);
      const requestMethod = typeof route === "function" ? route : octokit.request;
      const method = options.method;
      const headers = options.headers;
      let url = options.url;
      return {
          [Symbol.asyncIterator]: () => ({
              async next() {
                  if (!url)
                      return { done: true };
                  const response = await requestMethod({ method, url, headers });
                  const normalizedResponse = normalizePaginatedListResponse(response);
                  // `response.headers.link` format:
                  // '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
                  // sets `url` to undefined if "next" URL is not present or `link` header is not set
                  url = ((normalizedResponse.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
                  return { value: normalizedResponse };
              },
          }),
      };
  }
  
  function paginate(octokit, route, parameters, mapFn) {
      if (typeof parameters === "function") {
          mapFn = parameters;
          parameters = undefined;
      }
      return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);
  }
  function gather(octokit, results, iterator, mapFn) {
      return iterator.next().then((result) => {
          if (result.done) {
              return results;
          }
          let earlyExit = false;
          function done() {
              earlyExit = true;
          }
          results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data);
          if (earlyExit) {
              return results;
          }
          return gather(octokit, results, iterator, mapFn);
      });
  }
  
  const composePaginateRest = Object.assign(paginate, { iterator });
  
  /**
   * @param octokit Octokit instance
   * @param options Options passed to Octokit constructor
   */
  function paginateRest(octokit) {
      return {
          paginate: Object.assign(paginate.bind(null, octokit), {
              iterator: iterator.bind(null, octokit),
          }),
      };
  }
  paginateRest.VERSION = VERSION$5;
  
  var distWeb$2 = {
  	__proto__: null,
  	composePaginateRest: composePaginateRest,
  	paginateRest: paginateRest
  };
  
  var utils$2 = createCommonjsModule(function (module, exports) {
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) {
      Object.defineProperty(o, "default", { enumerable: true, value: v });
  }) : function(o, v) {
      o["default"] = v;
  });
  var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
      __setModuleDefault(result, mod);
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getOctokitOptions = exports.GitHub = exports.context = void 0;
  const Context = __importStar(context);
  const Utils = __importStar(utils$1);
  // octokit + plugins
  
  
  
  exports.context = new Context.Context();
  const baseUrl = Utils.getApiBaseUrl();
  const defaults = {
      baseUrl,
      request: {
          agent: Utils.getProxyAgent(baseUrl)
      }
  };
  exports.GitHub = distWeb.Octokit.plugin(distWeb$1.restEndpointMethods, distWeb$2.paginateRest).defaults(defaults);
  /**
   * Convience function to correctly format Octokit Options to pass into the constructor.
   *
   * @param     token    the repo PAT or GITHUB_TOKEN
   * @param     options  other options to set
   */
  function getOctokitOptions(token, options) {
      const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller
      // Auth
      const auth = Utils.getAuthString(token, opts);
      if (auth) {
          opts.auth = auth;
      }
      return opts;
  }
  exports.getOctokitOptions = getOctokitOptions;
  
  });
  
  var github = createCommonjsModule(function (module, exports) {
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) {
      Object.defineProperty(o, "default", { enumerable: true, value: v });
  }) : function(o, v) {
      o["default"] = v;
  });
  var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
      __setModuleDefault(result, mod);
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getOctokit = exports.context = void 0;
  const Context = __importStar(context);
  
  exports.context = new Context.Context();
  /**
   * Returns a hydrated octokit ready to use for GitHub Actions
   *
   * @param     token    the repo PAT or GITHUB_TOKEN
   * @param     options  other options to set
   */
  function getOctokit(token, options) {
      return new utils$2.GitHub(utils$2.getOctokitOptions(token, options));
  }
  exports.getOctokit = getOctokit;
  
  });
  
  var github$1 = /*@__PURE__*/unwrapExports(github);
  
  /**
   * Returns parameters depending on the status of the workflow
   */
  
  const jobParameters = status => {
    return {
      success: {
        color: 'good',
        text: 'succeeded'
      },
      failure: {
        color: 'danger',
        text: 'failed'
      },
      cancelled: {
        color: 'warning',
        text: 'was cancelled.'
      }
    }[status];
  };
  /**
   * Returns message for slack based on event type
   */
  
  
  const getMessage = () => {
    const eventName = github.context.eventName;
    const runUrl = `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
    const commitId = github.context.sha.substring(0, 7);
  
    switch (eventName) {
      case 'pull_request':
        {
          var _context$payload$pull, _context$payload$pull2, _context$payload$pull3, _context$payload$repo, _context$payload$pull4;
  
          const pr = {
            title: (_context$payload$pull = github.context.payload.pull_request) == null ? void 0 : _context$payload$pull.title,
            number: (_context$payload$pull2 = github.context.payload.pull_request) == null ? void 0 : _context$payload$pull2.number,
            url: (_context$payload$pull3 = github.context.payload.pull_request) == null ? void 0 : _context$payload$pull3.html_url
          };
          const compareUrl = `${(_context$payload$repo = github.context.payload.repository) == null ? void 0 : _context$payload$repo.html_url}/compare/${(_context$payload$pull4 = github.context.payload.pull_request) == null ? void 0 : _context$payload$pull4.head.ref}`; // prettier-ignore
  
          return `Workflow <${runUrl}|${process.env.GITHUB_WORKFLOW}> (<${compareUrl}|${commitId}>) for PR <${pr.url}| #${pr.number} ${pr.title}>`;
        }
  
      case 'release':
        {
          var _context$payload$repo2;
  
          const release = {
            title: github.context.payload.release.name || github.context.payload.release.tag_name,
            url: github.context.payload.release.html_url,
            commit: `${(_context$payload$repo2 = github.context.payload.repository) == null ? void 0 : _context$payload$repo2.html_url}/commit/${github.context.sha}`
          }; // prettier-ignore
  
          return `Workflow <${runUrl}|${process.env.GITHUB_WORKFLOW}> (<${release.commit}|${commitId}>) for Release <${release.url}| ${release.title}>`;
        }
  
      case 'push':
        {
          if (github.context.payload.ref.includes('tags')) {
            var _context$payload$repo3;
  
            const pre = 'refs/tags/';
            const title = github.context.payload.ref.substring(pre.length);
            const tag = {
              title,
              commit: github.context.payload.compare,
              url: `${(_context$payload$repo3 = github.context.payload.repository) == null ? void 0 : _context$payload$repo3.html_url}/releases/tag/${title}`
            }; // prettier-ignore
  
            return `Workflow <${runUrl}|${process.env.GITHUB_WORKFLOW}> (<${tag.commit}|${commitId}>) for Tag <${tag.url}| ${tag.title}>`;
          }
  
          const commitMessage = github.context.payload.head_commit.message;
          const headCommit = {
            title: commitMessage.includes('\n') ? commitMessage.substring(0, commitMessage.indexOf('\n')) : commitMessage,
            url: github.context.payload.head_commit.url
          }; // Normal commit push
  
          return `Workflow <${runUrl}|${process.env.GITHUB_WORKFLOW}> (<${github.context.payload.compare}|${commitId}>) for Commit <${headCommit.url}| ${headCommit.title}>`;
        }
  
      case 'schedule':
        {
          return `Scheduled Workflow <${runUrl}|${process.env.GITHUB_WORKFLOW}>`;
        }
  
      case 'create':
        {
          if (github.context.payload.ref_type !== 'branch') {
            return null;
          }
  
          const pre = 'refs/heads/';
          const branchName = github.context.ref.substring(pre.length);
          const branchUrl = `${github.context.payload.repository.html_url}/tree/${branchName}`;
          return `Workflow <${runUrl}|${process.env.GITHUB_WORKFLOW}> for Creation of Branch <${branchUrl}|${branchName}>`;
        }
  
      case 'delete':
        {
          if (github.context.payload.ref_type !== 'branch') {
            return null;
          }
  
          const branchName = github.context.payload.ref;
          return `Workflow <${runUrl}|${process.env.GITHUB_WORKFLOW}> for Deletion of Branch \`${branchName}\``;
        }
  
      default:
        return null;
    }
  };
  /**
   * Sends message via slack
   */
  
  
  const notify = async (status, url) => {
    var _context$payload$repo4;
  
    const sender = github.context.payload.sender;
    const message = getMessage();
    core$1.debug(JSON.stringify(github.context));
  
    if (!message) {
      console.log(`We don't support the [${github.context.eventName}] event yet.`);
      return;
    }
  
    const attachment = {
      author_name: sender == null ? void 0 : sender.login,
      author_link: sender == null ? void 0 : sender.html_url,
      author_icon: sender == null ? void 0 : sender.avatar_url,
      color: jobParameters(status).color,
      footer: `<https://github.com/${process.env.GITHUB_REPOSITORY}|${process.env.GITHUB_REPOSITORY}>`,
      footer_icon: 'https://github.githubassets.com/favicon.ico',
      mrkdwn_in: ['text'],
      ts: new Date((_context$payload$repo4 = github.context.payload.repository) == null ? void 0 : _context$payload$repo4.pushed_at).getTime().toString(),
      text: `${message} ${jobParameters(status).text}`
    };
  
    if (github.context.eventName === 'schedule') {
      // Schedule event doesn't have a commit so we use the current time
      attachment.ts = new Date().getTime().toString();
    }
  
    const payload = {
      attachments: [attachment]
    };
    await got.post(url, {
      body: JSON.stringify(payload)
    });
  };
  
  function _extends() {
    _extends = Object.assign || function (target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i];
  
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key];
          }
        }
      }
  
      return target;
    };
  
    return _extends.apply(this, arguments);
  }
  
  const getJobs = async () => {
    const Octokit = github.getOctokit(process.env.GITHUB_TOKEN);
    const {
      data
    } = await Octokit.actions.listJobsForWorkflowRun(_extends({}, github.context.repo, {
      run_id: github.context.runId
    }));
    const currentJob = github.context.job;
    return data.jobs.map(a => ({
      name: a.name,
      conclusion: a.conclusion
    })).filter(a => a.name !== currentJob);
  };
  
  const getJobsStatus = async () => {
    const jobs = await getJobs();
  
    if (jobs.some(a => ['failure', 'timed_out'].includes(a.conclusion))) {
      return 'failure';
    }
  
    if (jobs.some(a => a.conclusion === 'cancelled')) {
      return 'cancelled';
    }
  
    return 'success';
  };
  
  async function run() {
    try {
      const url = process.env.SLACK_WEBHOOK_URL;
  
      if (!url) {
        throw new Error('Please set [SLACK_WEBHOOK_URL] environment variable');
      }
  
      let jobStatus = core$1.getInput('status');
  
      if (!jobStatus) {
        if (!process.env.GITHUB_TOKEN) {
          throw new Error('Please pass in [GITHUB_TOKEN] environment variable');
        }
  
        jobStatus = await getJobsStatus();
      } else {
        if (!['success', 'failure', 'cancelled'].includes(jobStatus)) {
          throw new Error('Unknown job status passed in.');
        }
      }
  
      await notify(jobStatus, url);
    } catch (error) {
      core$1.setFailed(error.message);
      core$1.debug(error.stack);
    }
  }
  
  run();
  