ivate key to decrypt
 * @param {String|Array<String>} options.passphrase - The user's passphrase(s)
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<PrivateKey>} The unlocked key object.
 * @async
 */
async function decryptKey({ privateKey, passphrase, config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  if (!privateKey.isPrivate()) {
    throw new Error('Cannot decrypt a public key');
  }
  const clonedPrivateKey = privateKey.clone(true);
  const passphrases = util.isArray(passphrase) ? passphrase : [passphrase];

  try {
    await Promise.all(clonedPrivateKey.getKeys().map(key => (
      // try to decrypt each key with any of the given passphrases
      util.anyPromise(passphrases.map(passphrase => key.keyPacket.decrypt(passphrase)))
    )));

    await clonedPrivateKey.validate(config$1);
    return clonedPrivateKey;
  } catch (err) {
    clonedPrivateKey.clearPrivateParams();
    throw util.wrapError('Error decrypting private key', err);
  }
}

/**
 * Lock a private key with the given passphrase.
 * This method does not change the original key.
 * @param {Object} options
 * @param {PrivateKey} options.privateKey - The private key to encrypt
 * @param {String|Array<String>} options.passphrase - If multiple passphrases, they should be in the same order as the packets each should encrypt
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<PrivateKey>} The locked key object.
 * @async
 */
async function encryptKey({ privateKey, passphrase, config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  if (!privateKey.isPrivate()) {
    throw new Error('Cannot encrypt a public key');
  }
  const clonedPrivateKey = privateKey.clone(true);

  const keys = clonedPrivateKey.getKeys();
  const passphrases = util.isArray(passphrase) ? passphrase : new Array(keys.length).fill(passphrase);
  if (passphrases.length !== keys.length) {
    throw new Error('Invalid number of passphrases given for key encryption');
  }

  try {
    await Promise.all(keys.map(async (key, i) => {
      const { keyPacket } = key;
      await keyPacket.encrypt(passphrases[i], config$1);
      keyPacket.clearPrivateParams();
    }));
    return clonedPrivateKey;
  } catch (err) {
    clonedPrivateKey.clearPrivateParams();
    throw util.wrapError('Error encrypting private key', err);
  }
}


///////////////////////////////////////////
//                                       //
//   Message encryption and decryption   //
//                                       //
///////////////////////////////////////////


/**
 * Encrypts a message using public keys, passwords or both at once. At least one of `encryptionKeys`, `passwords` or `sessionKeys`
 *   must be specified. If signing keys are specified, those will be used to sign the message.
 * @param {Object} options
 * @param {Message} options.message - Message to be encrypted as created by {@link createMessage}
 * @param {PublicKey|PublicKey[]} [options.encryptionKeys] - Array of keys or single key, used to encrypt the message
 * @param {PrivateKey|PrivateKey[]} [options.signingKeys] - Private keys for signing. If omitted message will not be signed
 * @param {String|String[]} [options.passwords] - Array of passwords or a single password to encrypt the message
 * @param {Object} [options.sessionKey] - Session key in the form: `{ data:Uint8Array, algorithm:String }`
 * @param {'armored'|'binary'|'object'} [options.format='armored'] - Format of the returned message
 * @param {Signature} [options.signature] - A detached signature to add to the encrypted message
 * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
 * @param {KeyID|KeyID[]} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each `signingKeyIDs[i]` corresponds to `signingKeys[i]`
 * @param {KeyID|KeyID[]} [options.encryptionKeyIDs=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each `encryptionKeyIDs[i]` corresponds to `encryptionKeys[i]`
 * @param {Date} [options.date=current date] - Override the creation date of the message signature
 * @param {Object|Object[]} [options.signingUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `signingKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
 * @param {Object|Object[]} [options.encryptionUserIDs=primary user IDs] - Array of user IDs to encrypt for, one per key in `encryptionKeys`, e.g. `[{ name: 'Robert Receiver', email: 'robert@openpgp.org' }]`
 * @param {Object|Object[]} [options.signatureNotations=[]] - Array of notations to add to the signatures, e.g. `[{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]`
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<MaybeStream<String>|MaybeStream<Uint8Array>>} Encrypted message (string if `armor` was true, the default; Uint8Array if `armor` was false).
 * @async
 * @static
 */
async function encrypt$5({ message, encryptionKeys, signingKeys, passwords, sessionKey, format = 'armored', signature = null, wildcard = false, signingKeyIDs = [], encryptionKeyIDs = [], date = new Date(), signingUserIDs = [], encryptionUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  checkMessage(message); checkOutputMessageFormat(format);
  encryptionKeys = toArray$1(encryptionKeys); signingKeys = toArray$1(signingKeys); passwords = toArray$1(passwords);
  signingKeyIDs = toArray$1(signingKeyIDs); encryptionKeyIDs = toArray$1(encryptionKeyIDs); signingUserIDs = toArray$1(signingUserIDs); encryptionUserIDs = toArray$1(encryptionUserIDs); signatureNotations = toArray$1(signatureNotations);
  if (rest.detached) {
    throw new Error("The `detached` option has been removed from openpgp.encrypt, separately call openpgp.sign instead. Don't forget to remove the `privateKeys` option as well.");
  }
  if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.encrypt, pass `encryptionKeys` instead');
  if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.encrypt, pass `signingKeys` instead');
  if (rest.armor !== undefined) throw new Error('The `armor` option has been removed from openpgp.encrypt, pass `format` instead.');
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  if (!signingKeys) {
    signingKeys = [];
  }
  const streaming = message.fromStream;
  try {
    if (signingKeys.length || signature) { // sign the message only if signing keys or signature is specified
      message = await message.sign(signingKeys, signature, signingKeyIDs, date, signingUserIDs, signatureNotations, config$1);
    }
    message = message.compress(
      await getPreferredAlgo('compression', encryptionKeys, date, encryptionUserIDs, config$1),
      config$1
    );
    message = await message.encrypt(encryptionKeys, passwords, sessionKey, wildcard, encryptionKeyIDs, date, encryptionUserIDs, config$1);
    if (format === 'object') return message;
    // serialize data
    const armor = format === 'armored';
    const data = armor ? message.armor(config$1) : message.write();
    return convertStream(data, streaming, armor ? 'utf8' : 'binary');
  } catch (err) {
    throw util.wrapError('Error encrypting message', err);
  }
}

/**
 * Decrypts a message with the user's private key, a session key or a password.
 * One of `decryptionKeys`, `sessionkeys` or `passwords` must be specified (passing a combination of these options is not supported).
 * @param {Object} options
 * @param {Message} options.message - The message object with the encrypted data
 * @param {PrivateKey|PrivateKey[]} [options.decryptionKeys] - Private keys with decrypted secret key data or session key
 * @param {String|String[]} [options.passwords] - Passwords to decrypt the message
 * @param {Object|Object[]} [options.sessionKeys] - Session keys in the form: { data:Uint8Array, algorithm:String }
 * @param {PublicKey|PublicKey[]} [options.verificationKeys] - Array of public keys or single key, to verify signatures
 * @param {Boolean} [options.expectSigned=false] - If true, data decryption fails if the message is not signed with the provided publicKeys
 * @param {'utf8'|'binary'} [options.format='utf8'] - Whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
 * @param {Signature} [options.signature] - Detached signature for verification
 * @param {Date} [options.date=current date] - Use the given date for verification instead of the current time
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<Object>} Object containing decrypted and verified message in the form:
 *
 *     {
 *       data: MaybeStream<String>, (if format was 'utf8', the default)
 *       data: MaybeStream<Uint8Array>, (if format was 'binary')
 *       filename: String,
 *       signatures: [
 *         {
 *           keyID: module:type/keyid~KeyID,
 *           verified: Promise<true>,
 *           signature: Promise<Signature>
 *         }, ...
 *       ]
 *     }
 *
 *     where `signatures` contains a separate entry for each signature packet found in the input message.
 * @async
 * @static
 */
async function decrypt$5({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  checkMessage(message); verificationKeys = toArray$1(verificationKeys); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords); sessionKeys = toArray$1(sessionKeys);
  if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decrypt, pass `decryptionKeys` instead');
  if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.decrypt, pass `verificationKeys` instead');
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  try {
    const decrypted = await message.decrypt(decryptionKeys, passwords, sessionKeys, date, config$1);
    if (!verificationKeys) {
      verificationKeys = [];
    }

    const result = {};
    result.signatures = signature ? await decrypted.verifyDetached(signature, verificationKeys, date, config$1) : await decrypted.verify(verificationKeys, date, config$1);
    result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
    result.filename = decrypted.getFilename();
    linkStreams(result, message);
    if (expectSigned) {
      if (verificationKeys.length === 0) {
        throw new Error('Verification keys are required to verify message signatures');
      }
      if (result.signatures.length === 0) {
        throw new Error('Message is not signed');
      }
      result.data = concat([
        result.data,
        fromAsync(async () => {
          await util.anyPromise(result.signatures.map(sig => sig.verified));
        })
      ]);
    }
    result.data = await convertStream(result.data, message.fromStream, format);
    return result;
  } catch (err) {
    throw util.wrapError('Error decrypting message', err);
  }
}


//////////////////////////////////////////
//                                      //
//   Message signing and verification   //
//                                      //
//////////////////////////////////////////


/**
 * Signs a message.
 * @param {Object} options
 * @param {CleartextMessage|Message} options.message - (cleartext) message to be signed
 * @param {PrivateKey|PrivateKey[]} options.signingKeys - Array of keys or single key with decrypted secret key data to sign cleartext
 * @param {'armored'|'binary'|'object'} [options.format='armored'] - Format of the returned message
 * @param {Boolean} [options.detached=false] - If the return value should contain a detached signature
 * @param {KeyID|KeyID[]} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
 * @param {Date} [options.date=current date] - Override the creation date of the signature
 * @param {Object|Object[]} [options.signingUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `signingKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
 * @param {Object|Object[]} [options.signatureNotations=[]] - Array of notations to add to the signatures, e.g. `[{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]`
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<MaybeStream<String|Uint8Array>>} Signed message (string if `armor` was true, the default; Uint8Array if `armor` was false).
 * @async
 * @static
 */
async function sign$6({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  checkCleartextOrMessage(message); checkOutputMessageFormat(format);
  signingKeys = toArray$1(signingKeys); signingKeyIDs = toArray$1(signingKeyIDs); signingUserIDs = toArray$1(signingUserIDs); signatureNotations = toArray$1(signatureNotations);

  if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.sign, pass `signingKeys` instead');
  if (rest.armor !== undefined) throw new Error('The `armor` option has been removed from openpgp.sign, pass `format` instead.');
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  if (message instanceof CleartextMessage && format === 'binary') throw new Error('Cannot return signed cleartext message in binary format');
  if (message instanceof CleartextMessage && detached) throw new Error('Cannot detach-sign a cleartext message');

  if (!signingKeys || signingKeys.length === 0) {
    throw new Error('No signing keys provided');
  }

  try {
    let signature;
    if (detached) {
      signature = await message.signDetached(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, signatureNotations, config$1);
    } else {
      signature = await message.sign(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, signatureNotations, config$1);
    }
    if (format === 'object') return signature;

    const armor = format === 'armored';
    signature = armor ? signature.armor(config$1) : signature.write();
    if (detached) {
      signature = transformPair(message.packets.write(), async (readable, writable) => {
        await Promise.all([
          pipe(signature, writable),
          readToEnd(readable).catch(() => {})
        ]);
      });
    }
    return convertStream(signature, message.fromStream, armor ? 'utf8' : 'binary');
  } catch (err) {
    throw util.wrapError('Error signing message', err);
  }
}

/**
 * Verifies signatures of cleartext signed message
 * @param {Object} options
 * @param {CleartextMessage|Message} options.message - (cleartext) message object with signatures
 * @param {PublicKey|PublicKey[]} options.verificationKeys - Array of publicKeys or single key, to verify signatures
 * @param {Boolean} [options.expectSigned=false] - If true, verification throws if the message is not signed with the provided publicKeys
 * @param {'utf8'|'binary'} [options.format='utf8'] - Whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
 * @param {Signature} [options.signature] - Detached signature for verification
 * @param {Date} [options.date=current date] - Use the given date for verification instead of the current time
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<Object>} Object containing verified message in the form:
 *
 *     {
 *       data: MaybeStream<String>, (if `message` was a CleartextMessage)
 *       data: MaybeStream<Uint8Array>, (if `message` was a Message)
 *       signatures: [
 *         {
 *           keyID: module:type/keyid~KeyID,
 *           verified: Promise<true>,
 *           signature: Promise<Signature>
 *         }, ...
 *       ]
 *     }
 *
 *     where `signatures` contains a separate entry for each signature packet found in the input message.
 * @async
 * @static
 */
async function verify$6({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  checkCleartextOrMessage(message); verificationKeys = toArray$1(verificationKeys);
  if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.verify, pass `verificationKeys` instead');
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  if (message instanceof CleartextMessage && format === 'binary') throw new Error("Can't return cleartext message data as binary");
  if (message instanceof CleartextMessage && signature) throw new Error("Can't verify detached cleartext signature");

  try {
    const result = {};
    if (signature) {
      result.signatures = await message.verifyDetached(signature, verificationKeys, date, config$1);
    } else {
      result.signatures = await message.verify(verificationKeys, date, config$1);
    }
    result.data = format === 'binary' ? message.getLiteralData() : message.getText();
    if (message.fromStream && !signature) linkStreams(result, message);
    if (expectSigned) {
      if (result.signatures.length === 0) {
        throw new Error('Message is not signed');
      }
      result.data = concat([
        result.data,
        fromAsync(async () => {
          await util.anyPromise(result.signatures.map(sig => sig.verified));
        })
      ]);
    }
    result.data = await convertStream(result.data, message.fromStream, format);
    return result;
  } catch (err) {
    throw util.wrapError('Error verifying signed message', err);
  }
}


///////////////////////////////////////////////
//                                           //
//   Session key encryption and decryption   //
//                                           //
///////////////////////////////////////////////

/**
 * Generate a new session key object, taking the algorithm preferences of the passed public keys into account, if any.
 * @param {Object} options
 * @param {PublicKey|PublicKey[]} [options.encryptionKeys] - Array of public keys or single key used to select algorithm preferences for. If no keys are given, the algorithm will be [config.preferredSymmetricAlgorithm]{@link module:config.preferredSymmetricAlgorithm}
 * @param {Date} [options.date=current date] - Date to select algorithm preferences at
 * @param {Object|Object[]} [options.encryptionUserIDs=primary user IDs] - User IDs to select algorithm preferences for
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<{ data: Uint8Array, algorithm: String }>} Object with session key data and algorithm.
 * @async
 * @static
 */
async function generateSessionKey$1({ encryptionKeys, date = new Date(), encryptionUserIDs = [], config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  encryptionKeys = toArray$1(encryptionKeys); encryptionUserIDs = toArray$1(encryptionUserIDs);
  if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.generateSessionKey, pass `encryptionKeys` instead');
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  try {
    const sessionKeys = await Message.generateSessionKey(encryptionKeys, date, encryptionUserIDs, config$1);
    return sessionKeys;
  } catch (err) {
    throw util.wrapError('Error generating session key', err);
  }
}

/**
 * Encrypt a symmetric session key with public keys, passwords, or both at once.
 * At least one of `encryptionKeys` or `passwords` must be specified.
 * @param {Object} options
 * @param {Uint8Array} options.data - The session key to be encrypted e.g. 16 random bytes (for aes128)
 * @param {String} options.algorithm - Algorithm of the symmetric session key e.g. 'aes128' or 'aes256'
 * @param {String} [options.aeadAlgorithm] - AEAD algorithm, e.g. 'eax' or 'ocb'
 * @param {PublicKey|PublicKey[]} [options.encryptionKeys] - Array of public keys or single key, used to encrypt the key
 * @param {String|String[]} [options.passwords] - Passwords for the message
 * @param {'armored'|'binary'} [options.format='armored'] - Format of the returned value
 * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
 * @param {KeyID|KeyID[]} [options.encryptionKeyIDs=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to encryptionKeys[i]
 * @param {Date} [options.date=current date] - Override the date
 * @param {Object|Object[]} [options.encryptionUserIDs=primary user IDs] - Array of user IDs to encrypt for, one per key in `encryptionKeys`, e.g. `[{ name: 'Phil Zimmermann', email: 'phil@openpgp.org' }]`
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<String|Uint8Array>} Encrypted session keys (string if `armor` was true, the default; Uint8Array if `armor` was false).
 * @async
 * @static
 */
async function encryptSessionKey({ data, algorithm, aeadAlgorithm, encryptionKeys, passwords, format = 'armored', wildcard = false, encryptionKeyIDs = [], date = new Date(), encryptionUserIDs = [], config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  checkBinary(data); checkString(algorithm, 'algorithm'); checkOutputMessageFormat(format);
  encryptionKeys = toArray$1(encryptionKeys); passwords = toArray$1(passwords); encryptionKeyIDs = toArray$1(encryptionKeyIDs); encryptionUserIDs = toArray$1(encryptionUserIDs);
  if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.encryptSessionKey, pass `encryptionKeys` instead');
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  if ((!encryptionKeys || encryptionKeys.length === 0) && (!passwords || passwords.length === 0)) {
    throw new Error('No encryption keys or passwords provided.');
  }

  try {
    const message = await Message.encryptSessionKey(data, algorithm, aeadAlgorithm, encryptionKeys, passwords, wildcard, encryptionKeyIDs, date, encryptionUserIDs, config$1);
    return formatObject(message, format, config$1);
  } catch (err) {
    throw util.wrapError('Error encrypting session key', err);
  }
}

/**
 * Decrypt symmetric session keys using private keys or passwords (not both).
 * One of `decryptionKeys` or `passwords` must be specified.
 * @param {Object} options
 * @param {Message} options.message - A message object containing the encrypted session key packets
 * @param {PrivateKey|PrivateKey[]} [options.decryptionKeys] - Private keys with decrypted secret key data
 * @param {String|String[]} [options.passwords] - Passwords to decrypt the session key
 * @param {Date} [options.date] - Date to use for key verification instead of the current time
 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
 * @returns {Promise<Object[]>} Array of decrypted session key, algorithm pairs in the form:
 *                                            { data:Uint8Array, algorithm:String }
 * @throws if no session key could be found or decrypted
 * @async
 * @static
 */
async function decryptSessionKeys({ message, decryptionKeys, passwords, date = new Date(), config: config$1, ...rest }) {
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
  checkMessage(message); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords);
  if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decryptSessionKeys, pass `decryptionKeys` instead');
  const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);

  try {
    const sessionKeys = await message.decryptSessionKeys(decryptionKeys, passwords, date, config$1);
    return sessionKeys;
  } catch (err) {
    throw util.wrapError('Error decrypting session keys', err);
  }
}


//////////////////////////
//                      //
//   Helper functions   //
//                      //
//////////////////////////


/**
 * Input validation
 * @private
 */
function checkString(data, name) {
  if (!util.isString(data)) {
    throw new Error('Parameter [' + (name || 'data') + '] must be of type String');
  }
}
function checkBinary(data, name) {
  if (!util.isUint8Array(data)) {
    throw new Error('Parameter [' + (name || 'data') + '] must be of type Uint8Array');
  }
}
function checkMessage(message) {
  if (!(message instanceof Message)) {
    throw new Error('Parameter [message] needs to be of type Message');
  }
}
function checkCleartextOrMessage(message) {
  if (!(message instanceof CleartextMessage) && !(message instanceof Message)) {
    throw new Error('Parameter [message] needs to be of type Message or CleartextMessage');
  }
}
function checkOutputMessageFormat(format) {
  if (format !== 'armored' && format !== 'binary' && format !== 'object') {
    throw new Error(`Unsupported format ${format}`);
  }
}
const defaultConfigPropsCount = Object.keys(config).length;
function checkConfig(config$1) {
  const inputConfigProps = Object.keys(config$1);
  if (inputConfigProps.length !== defaultConfigPropsCount) {
    for (const inputProp of inputConfigProps) {
      if (config[inputProp] === undefined) {
        throw new Error(`Unknown config property: ${inputProp}`);
      }
    }
  }
}

/**
 * Normalize parameter to an array if it is not undefined.
 * @param {Object} param - the parameter to be normalized
 * @returns {Array<Object>|undefined} The resulting array or undefined.
 * @private
 */
function toArray$1(param) {
  if (param && !util.isArray(param)) {
    param = [param];
  }
  return param;
}

/**
 * Convert data to or from Stream
 * @param {Object} data - the data to convert
 * @param {'web'|'ponyfill'|'node'|false} streaming - Whether to return a ReadableStream, and of what type
 * @param {'utf8'|'binary'} [encoding] - How to return data in Node Readable streams
 * @returns {Promise<Object>} The data in the respective format.
 * @async
 * @private
 */
async function convertStream(data, streaming, encoding = 'utf8') {
  const streamType = util.isStream(data);
  if (streamType === 'array') {
    return readToEnd(data);
  }
  if (streaming === 'node') {
    data = webToNode(data);
    if (encoding !== 'binary') data.setEncoding(encoding);
    return data;
  }
  if (streaming === 'web' && streamType === 'ponyfill') {
    return toNativeReadable(data);
  }
  return data;
}

/**
 * Link result.data to the message stream for cancellation.
 * Also, forward errors in the message to result.data.
 * @param {Object} result - the data to convert
 * @param {Message} message - message object
 * @returns {Object}
 * @private
 */
function linkStreams(result, message) {
  result.data = transformPair(message.packets.stream, async (readable, writable) => {
    await pipe(result.data, writable, {
      preventClose: true
    });
    const writer = getWriter(writable);
    try {
      // Forward errors in the message stream to result.data.
      await readToEnd(readable, _ => _);
      await writer.close();
    } catch (e) {
      await writer.abort(e);
    }
  });
}

/**
 * Convert the object to the given format
 * @param {Key|Message} object
 * @param {'armored'|'binary'|'object'} format
 * @param {Object} config - Full configuration
 * @returns {String|Uint8Array|Object}
 */
function formatObject(object, format, config) {
  switch (format) {
    case 'object':
      return object;
    case 'armored':
      return object.armor(config);
    case 'binary':
      return object.write();
    default:
      throw new Error(`Unsupported format ${format}`);
  }
}

/**
 * web-streams-polyfill v3.0.3
 */
/// <reference lib="es2015.symbol" />
const SymbolPolyfill = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ?
    Symbol :
    description => `Symbol(${description})`;

/// <reference lib="dom" />
function noop() {
    return undefined;
}
function getGlobals() {
    if (typeof self !== 'undefined') {
        return self;
    }
    else if (typeof window !== 'undefined') {
        return window;
    }
    else if (typeof global !== 'undefined') {
        return global;
    }
    return undefined;
}
const globals = getGlobals();

function typeIsObject(x) {
    return (typeof x === 'object' && x !== null) || typeof x === 'function';
}
const rethrowAssertionErrorRejection = noop;

const originalPromise = Promise;
const originalPromiseThen = Promise.prototype.then;
const originalPromiseResolve = Promise.resolve.bind(originalPromise);
const originalPromiseReject = Promise.reject.bind(originalPromise);
function newPromise(executor) {
    return new originalPromise(executor);
}
function promiseResolvedWith(value) {
    return originalPromiseResolve(value);
}
function promiseRejectedWith(reason) {
    return originalPromiseReject(reason);
}
function PerformPromiseThen(promise, onFulfilled, onRejected) {
    // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an
    // approximation.
    return originalPromiseThen.call(promise, onFulfilled, onRejected);
}
function uponPromise(promise, onFulfilled, onRejected) {
    PerformPromiseThen(PerformPromiseThen(promise, onFulfilled, onRejected), undefined, rethrowAssertionErrorRejection);
}
function uponFulfillment(promise, onFulfilled) {
    uponPromise(promise, onFulfilled);
}
function uponRejection(promise, onRejected) {
    uponPromise(promise, undefined, onRejected);
}
function transformPromiseWith(promise, fulfillmentHandler, rejectionHandler) {
    return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler);
}
function setPromiseIsHandledToTrue(promise) {
    PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection);
}
const queueMicrotask = (() => {
    const globalQueueMicrotask = globals && globals.queueMicrotask;
    if (typeof globalQueueMicrotask === 'function') {
        return globalQueueMicrotask;
    }
    const resolvedPromise = promiseResolvedWith(undefined);
    return (fn) => PerformPromiseThen(resolvedPromise, fn);
})();
function reflectCall(F, V, args) {
    if (typeof F !== 'function') {
        throw new TypeError('Argument is not a function');
    }
    return Function.prototype.apply.call(F, V, args);
}
function promiseCall(F, V, args) {
    try {
        return promiseResolvedWith(reflectCall(F, V, args));
    }
    catch (value) {
        return promiseRejectedWith(value);
    }
}

// Original from Chromium
// https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js
const QUEUE_MAX_ARRAY_SIZE = 16384;
/**
 * Simple queue structure.
 *
 * Avoids scalability issues with using a packed array directly by using
 * multiple arrays in a linked list and keeping the array size bounded.
 */
class SimpleQueue {
    constructor() {
        this._cursor = 0;
        this._size = 0;
        // _front and _back are always defined.
        this._front = {
            _elements: [],
            _next: undefined
        };
        this._back = this._front;
        // The cursor is used to avoid calling Array.shift().
        // It contains the index of the front element of the array inside the
        // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE).
        this._cursor = 0;
        // When there is only one node, size === elements.length - cursor.
        this._size = 0;
    }
    get length() {
        return this._size;
    }
    // For exception safety, this method is structured in order:
    // 1. Read state
    // 2. Calculate required state mutations
    // 3. Perform state mutations
    push(element) {
        const oldBack = this._back;
        let newBack = oldBack;
        if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) {
            newBack = {
                _elements: [],
                _next: undefined
            };
        }
        // push() is the mutation most likely to throw an exception, so it
        // goes first.
        oldBack._elements.push(element);
        if (newBack !== oldBack) {
            this._back = newBack;
            oldBack._next = newBack;
        }
        ++this._size;
    }
    // Like push(), shift() follows the read -> calculate -> mutate pattern for
    // exception safety.
    shift() { // must not be called on an empty queue
        const oldFront = this._front;
        let newFront = oldFront;
        const oldCursor = this._cursor;
        let newCursor = oldCursor + 1;
        const elements = oldFront._elements;
        const element = elements[oldCursor];
        if (newCursor === QUEUE_MAX_ARRAY_SIZE) {
            newFront = oldFront._next;
            newCursor = 0;
        }
        // No mutations before this point.
        --this._size;
        this._cursor = newCursor;
        if (oldFront !== newFront) {
            this._front = newFront;
        }
        // Permit shifted element to be garbage collected.
        elements[oldCursor] = undefined;
        return element;
    }
    // The tricky thing about forEach() is that it can be called
    // re-entrantly. The queue may be mutated inside the callback. It is easy to
    // see that push() within the callback has no negative effects since the end
    // of the queue is checked for on every iteration. If shift() is called
    // repeatedly within the callback then the next iteration may return an
    // element that has been removed. In this case the callback will be called
    // with undefined values until we either "catch up" with elements that still
    // exist or reach the back of the queue.
    forEach(callback) {
        let i = this._cursor;
        let node = this._front;
        let elements = node._elements;
        while (i !== elements.length || node._next !== undefined) {
            if (i === elements.length) {
                node = node._next;
                elements = node._elements;
                i = 0;
                if (elements.length === 0) {
                    break;
                }
            }
            callback(elements[i]);
            ++i;
        }
    }
    // Return the element that would be returned if shift() was called now,
    // without modifying the queue.
    peek() { // must not be called on an empty queue
        const front = this._front;
        const cursor = this._cursor;
        return front._elements[cursor];
    }
}

function ReadableStreamReaderGenericInitialize(reader, stream) {
    reader._ownerReadableStream = stream;
    stream._reader = reader;
    if (stream._state === 'readable') {
        defaultReaderClosedPromiseInitialize(reader);
    }
    else if (stream._state === 'closed') {
        defaultReaderClosedPromiseInitializeAsResolved(reader);
    }
    else {
        defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError);
    }
}
// A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state
// check.
function ReadableStreamReaderGenericCancel(reader, reason) {
    const stream = reader._ownerReadableStream;
    return ReadableStreamCancel(stream, reason);
}
function ReadableStreamReaderGenericRelease(reader) {
    if (reader._ownerReadableStream._state === 'readable') {
        defaultReaderClosedPromiseReject(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
    }
    else {
        defaultReaderClosedPromiseResetToRejected(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
    }
    reader._ownerReadableStream._reader = undefined;
    reader._ownerReadableStream = undefined;
}
// Helper functions for the readers.
function readerLockException(name) {
    return new TypeError('Cannot ' + name + ' a stream using a released reader');
}
// Helper functions for the ReadableStreamDefaultReader.
function defaultReaderClosedPromiseInitialize(reader) {
    reader._closedPromise = newPromise((resolve, reject) => {
        reader._closedPromise_resolve = resolve;
        reader._closedPromise_reject = reject;
    });
}
function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) {
    defaultReaderClosedPromiseInitialize(reader);
    defaultReaderClosedPromiseReject(reader, reason);
}
function defaultReaderClosedPromiseInitializeAsResolved(reader) {
    defaultReaderClosedPromiseInitialize(reader);
    defaultReaderClosedPromiseResolve(reader);
}
function defaultReaderClosedPromiseReject(reader, reason) {
    if (reader._closedPromise_reject === undefined) {
        return;
    }
    setPromiseIsHandledToTrue(reader._closedPromise);
    reader._closedPromise_reject(reason);
    reader._closedPromise_resolve = undefined;
    reader._closedPromise_reject = undefined;
}
function defaultReaderClosedPromiseResetToRejected(reader, reason) {
    defaultReaderClosedPromiseInitializeAsRejected(reader, reason);
}
function defaultReaderClosedPromiseResolve(reader) {
    if (reader._closedPromise_resolve === undefined) {
        return;
    }
    reader._closedPromise_resolve(undefined);
    reader._closedPromise_resolve = undefined;
    reader._closedPromise_reject = undefined;
}

const AbortSteps = SymbolPolyfill('[[AbortSteps]]');
const ErrorSteps = SymbolPolyfill('[[ErrorSteps]]');
const CancelSteps = SymbolPolyfill('[[CancelSteps]]');
const PullSteps = SymbolPolyfill('[[PullSteps]]');

/// <reference lib="es2015.core" />
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill
const NumberIsFinite = Number.isFinite || function (x) {
    return typeof x === 'number' && isFinite(x);
};

/// <reference lib="es2015.core" />
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill
const MathTrunc = Math.trunc || function (v) {
    return v < 0 ? Math.ceil(v) : Math.floor(v);
};

// https://heycam.github.io/webidl/#idl-dictionaries
function isDictionary(x) {
    return typeof x === 'object' || typeof x === 'function';
}
function assertDictionary(obj, context) {
    if (obj !== undefined && !isDictionary(obj)) {
        throw new TypeError(`${context} is not an object.`);
    }
}
// https://heycam.github.io/webidl/#idl-callback-functions
function assertFunction(x, context) {
    if (typeof x !== 'function') {
        throw new TypeError(`${context} is not a function.`);
    }
}
// https://heycam.github.io/webidl/#idl-object
function isObject(x) {
    return (typeof x === 'object' && x !== null) || typeof x === 'function';
}
function assertObject(x, context) {
    if (!isObject(x)) {
        throw new TypeError(`${context} is not an object.`);
    }
}
function assertRequiredArgument(x, position, context) {
    if (x === undefined) {
        throw new TypeError(`Parameter ${position} is required in '${context}'.`);
    }
}
function assertRequiredField(x, field, context) {
    if (x === undefined) {
        throw new TypeError(`${field} is required in '${context}'.`);
    }
}
// https://heycam.github.io/webidl/#idl-unrestricted-double
function convertUnrestrictedDouble(value) {
    return Number(value);
}
function censorNegativeZero(x) {
    return x === 0 ? 0 : x;
}
function integerPart(x) {
    return censorNegativeZero(MathTrunc(x));
}
// https://heycam.github.io/webidl/#idl-unsigned-long-long
function convertUnsignedLongLongWithEnforceRange(value, context) {
    const lowerBound = 0;
    const upperBound = Number.MAX_SAFE_INTEGER;
    let x = Number(value);
    x = censorNegativeZero(x);
    if (!NumberIsFinite(x)) {
        throw new TypeError(`${context} is not a finite number`);
    }
    x = integerPart(x);
    if (x < lowerBound || x > upperBound) {
        throw new TypeError(`${context} is outside the accepted range of ${lowerBound} to ${upperBound}, inclusive`);
    }
    if (!NumberIsFinite(x) || x === 0) {
        return 0;
    }
    // TODO Use BigInt if supported?
    // let xBigInt = BigInt(integerPart(x));
    // xBigInt = BigInt.asUintN(64, xBigInt);
    // return Number(xBigInt);
    return x;
}

function assertReadableStream(x, context) {
    if (!IsReadableStream(x)) {
        throw new TypeError(`${context} is not a ReadableStream.`);
    }
}

// Abstract operations for the ReadableStream.
function AcquireReadableStreamDefaultReader(stream) {
    return new ReadableStreamDefaultReader(stream);
}
// ReadableStream API exposed for controllers.
function ReadableStreamAddReadRequest(stream, readRequest) {
    stream._reader._readRequests.push(readRequest);
}
function ReadableStreamFulfillReadRequest(stream, chunk, done) {
    const reader = stream._reader;
    const readRequest = reader._readRequests.shift();
    if (done) {
        readRequest._closeSteps();
    }
    else {
        readRequest._chunkSteps(chunk);
    }
}
function ReadableStreamGetNumReadRequests(stream) {
    return stream._reader._readRequests.length;
}
function ReadableStreamHasDefaultReader(stream) {
    const reader = stream._reader;
    if (reader === undefined) {
        return false;
    }
    if (!IsReadableStreamDefaultReader(reader)) {
        return false;
    }
    return true;
}
/**
 * A default reader vended by a {@link ReadableStream}.
 *
 * @public
 */
class ReadableStreamDefaultReader {
    constructor(stream) {
        assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader');
        assertReadableStream(stream, 'First parameter');
        if (IsReadableStreamLocked(stream)) {
            throw new TypeError('This stream has already been locked for exclusive reading by another reader');
        }
        ReadableStreamReaderGenericInitialize(this, stream);
        this._readRequests = new SimpleQueue();
    }
    /**
     * Returns a promise that will be fulfilled when the stream becomes closed,
     * or rejected if the stream ever errors or the reader's lock is released before the stream finishes closing.
     */
    get closed() {
        if (!IsReadableStreamDefaultReader(this)) {
            return promiseRejectedWith(defaultReaderBrandCheckException('closed'));
        }
        return this._closedPromise;
    }
    /**
     * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
     */
    cancel(reason = undefined) {
        if (!IsReadableStreamDefaultReader(this)) {
            return promiseRejectedWith(defaultReaderBrandCheckException('cancel'));
        }
        if (this._ownerReadableStream === undefined) {
            return promiseRejectedWith(readerLockException('cancel'));
        }
        return ReadableStreamReaderGenericCancel(this, reason);
    }
    /**
     * Returns a promise that allows access to the next chunk from the stream's internal queue, if available.
     *
     * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
     */
    read() {
        if (!IsReadableStreamDefaultReader(this)) {
            return promiseRejectedWith(defaultReaderBrandCheckException('read'));
        }
        if (this._ownerReadableStream === undefined) {
            return promiseRejectedWith(readerLockException('read from'));
        }
        let resolvePromise;
        let rejectPromise;
        const promise = newPromise((resolve, reject) => {
            resolvePromise = resolve;
            rejectPromise = reject;
        });
        const readRequest = {
            _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
            _closeSteps: () => resolvePromise({ value: undefined, done: true }),
            _errorSteps: e => rejectPromise(e)
        };
        ReadableStreamDefaultReaderRead(this, readRequest);
        return promise;
    }
    /**
     * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
     * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
     * from now on; otherwise, the reader will appear closed.
     *
     * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
     * the reader's {@link ReadableStreamDefaultReader.read | read()} method has not yet been settled. Attempting to
     * do so will throw a `TypeError` and leave the reader locked to the stream.
     */
    releaseLock() {
        if (!IsReadableStreamDefaultReader(this)) {
            throw defaultReaderBrandCheckException('releaseLock');
        }
        if (this._ownerReadableStream === undefined) {
            return;
        }
        if (this._readRequests.length > 0) {
            throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
        }
        ReadableStreamReaderGenericRelease(this);
    }
}
Object.defineProperties(ReadableStreamDefaultReader.prototype, {
    cancel: { enumerable: true },
    read: { enumerable: true },
    releaseLock: { enumerable: true },
    closed: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(ReadableStreamDefaultReader.prototype, SymbolPolyfill.toStringTag, {
        value: 'ReadableStreamDefaultReader',
        configurable: true
    });
}
// Abstract operations for the readers.
function IsReadableStreamDefaultReader(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) {
        return false;
    }
    return true;
}
function ReadableStreamDefaultReaderRead(reader, readRequest) {
    const stream = reader._ownerReadableStream;
    stream._disturbed = true;
    if (stream._state === 'closed') {
        readRequest._closeSteps();
    }
    else if (stream._state === 'errored') {
        readRequest._errorSteps(stream._storedError);
    }
    else {
        stream._readableStreamController[PullSteps](readRequest);
    }
}
// Helper functions for the ReadableStreamDefaultReader.
function defaultReaderBrandCheckException(name) {
    return new TypeError(`ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`);
}

/// <reference lib="es2018.asynciterable" />
let AsyncIteratorPrototype;
if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
    // We're running inside a ES2018+ environment, but we're compiling to an older syntax.
    // We cannot access %AsyncIteratorPrototype% without non-ES2018 syntax, but we can re-create it.
    AsyncIteratorPrototype = {
        // 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )
        // https://tc39.github.io/ecma262/#sec-asynciteratorprototype-asynciterator
        [SymbolPolyfill.asyncIterator]() {
            return this;
        }
    };
    Object.defineProperty(AsyncIteratorPrototype, SymbolPolyfill.asyncIterator, { enumerable: false });
}

/// <reference lib="es2018.asynciterable" />
class ReadableStreamAsyncIteratorImpl {
    constructor(reader, preventCancel) {
        this._ongoingPromise = undefined;
        this._isFinished = false;
        this._reader = reader;
        this._preventCancel = preventCancel;
    }
    next() {
        const nextSteps = () => this._nextSteps();
        this._ongoingPromise = this._ongoingPromise ?
            transformPromiseWith(this._ongoingPromise, nextSteps, nextSteps) :
            nextSteps();
        return this._ongoingPromise;
    }
    return(value) {
        const returnSteps = () => this._returnSteps(value);
        return this._ongoingPromise ?
            transformPromiseWith(this._ongoingPromise, returnSteps, returnSteps) :
            returnSteps();
    }
    _nextSteps() {
        if (this._isFinished) {
            return Promise.resolve({ value: undefined, done: true });
        }
        const reader = this._reader;
        if (reader._ownerReadableStream === undefined) {
            return promiseRejectedWith(readerLockException('iterate'));
        }
        let resolvePromise;
        let rejectPromise;
        const promise = newPromise((resolve, reject) => {
            resolvePromise = resolve;
            rejectPromise = reject;
        });
        const readRequest = {
            _chunkSteps: chunk => {
                this._ongoingPromise = undefined;
                // This needs to be delayed by one microtask, otherwise we stop pulling too early which breaks a test.
                // FIXME Is this a bug in the specification, or in the test?
                queueMicrotask(() => resolvePromise({ value: chunk, done: false }));
            },
            _closeSteps: () => {
                this._ongoingPromise = undefined;
                this._isFinished = true;
                ReadableStreamReaderGenericRelease(reader);
                resolvePromise({ value: undefined, done: true });
            },
            _errorSteps: reason => {
                this._ongoingPromise = undefined;
                this._isFinished = true;
                ReadableStreamReaderGenericRelease(reader);
                rejectPromise(reason);
            }
        };
        ReadableStreamDefaultReaderRead(reader, readRequest);
        return promise;
    }
    _returnSteps(value) {
        if (this._isFinished) {
            return Promise.resolve({ value, done: true });
        }
        this._isFinished = true;
        const reader = this._reader;
        if (reader._ownerReadableStream === undefined) {
            return promiseRejectedWith(readerLockException('finish iterating'));
        }
        if (!this._preventCancel) {
            const result = ReadableStreamReaderGenericCancel(reader, value);
            ReadableStreamReaderGenericRelease(reader);
            return transformPromiseWith(result, () => ({ value, done: true }));
        }
        ReadableStreamReaderGenericRelease(reader);
        return promiseResolvedWith({ value, done: true });
    }
}
const ReadableStreamAsyncIteratorPrototype = {
    next() {
        if (!IsReadableStreamAsyncIterator(this)) {
            return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next'));
        }
        return this._asyncIteratorImpl.next();
    },
    return(value) {
        if (!IsReadableStreamAsyncIterator(this)) {
            return promiseRejectedWith(streamAsyncIteratorBrandCheckException('return'));
        }
        return this._asyncIteratorImpl.return(value);
    }
};
if (AsyncIteratorPrototype !== undefined) {
    Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);
}
// Abstract operations for the ReadableStream.
function AcquireReadableStreamAsyncIterator(stream, preventCancel) {
    const reader = AcquireReadableStreamDefaultReader(stream);
    const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel);
    const iterator = Object.create(ReadableStreamAsyncIteratorPrototype);
    iterator._asyncIteratorImpl = impl;
    return iterator;
}
function IsReadableStreamAsyncIterator(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorImpl')) {
        return false;
    }
    return true;
}
// Helper functions for the ReadableStream.
function streamAsyncIteratorBrandCheckException(name) {
    return new TypeError(`ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator`);
}

/// <reference lib="es2015.core" />
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill
const NumberIsNaN = Number.isNaN || function (x) {
    // eslint-disable-next-line no-self-compare
    return x !== x;
};

function IsFiniteNonNegativeNumber(v) {
    if (!IsNonNegativeNumber(v)) {
        return false;
    }
    if (v === Infinity) {
        return false;
    }
    return true;
}
function IsNonNegativeNumber(v) {
    if (typeof v !== 'number') {
        return false;
    }
    if (NumberIsNaN(v)) {
        return false;
    }
    if (v < 0) {
        return false;
    }
    return true;
}

function DequeueValue(container) {
    const pair = container._queue.shift();
    container._queueTotalSize -= pair.size;
    if (container._queueTotalSize < 0) {
        container._queueTotalSize = 0;
    }
    return pair.value;
}
function EnqueueValueWithSize(container, value, size) {
    size = Number(size);
    if (!IsFiniteNonNegativeNumber(size)) {
        throw new RangeError('Size must be a finite, non-NaN, non-negative number.');
    }
    container._queue.push({ value, size });
    container._queueTotalSize += size;
}
function PeekQueueValue(container) {
    const pair = container._queue.peek();
    return pair.value;
}
function ResetQueue(container) {
    container._queue = new SimpleQueue();
    container._queueTotalSize = 0;
}

function CreateArrayFromList(elements) {
    // We use arrays to represent lists, so this is basically a no-op.
    // Do a slice though just in case we happen to depend on the unique-ness.
    return elements.slice();
}
function CopyDataBlockBytes(dest, destOffset, src, srcOffset, n) {
    new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset);
}
// Not implemented correctly
function TransferArrayBuffer(O) {
    return O;
}
// Not implemented correctly
function IsDetachedBuffer(O) {
    return false;
}

/**
 * A pull-into request in a {@link ReadableByteStreamController}.
 *
 * @public
 */
class ReadableStreamBYOBRequest {
    constructor() {
        throw new TypeError('Illegal constructor');
    }
    /**
     * Returns the view for writing in to, or `null` if the BYOB request has already been responded to.
     */
    get view() {
        if (!IsReadableStreamBYOBRequest(this)) {
            throw byobRequestBrandCheckException('view');
        }
        return this._view;
    }
    respond(bytesWritten) {
        if (!IsReadableStreamBYOBRequest(this)) {
            throw byobRequestBrandCheckException('respond');
        }
        assertRequiredArgument(bytesWritten, 1, 'respond');
        bytesWritten = convertUnsignedLongLongWithEnforceRange(bytesWritten, 'First parameter');
        if (this._associatedReadableByteStreamController === undefined) {
            throw new TypeError('This BYOB request has been invalidated');
        }
        if (IsDetachedBuffer(this._view.buffer)) ;
        ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten);
    }
    respondWithNewView(view) {
        if (!IsReadableStreamBYOBRequest(this)) {
            throw byobRequestBrandCheckException('respondWithNewView');
        }
        assertRequiredArgument(view, 1, 'respondWithNewView');
        if (!ArrayBuffer.isView(view)) {
            throw new TypeError('You can only respond with array buffer views');
        }
        if (view.byteLength === 0) {
            throw new TypeError('chunk must have non-zero byteLength');
        }
        if (view.buffer.byteLength === 0) {
            throw new TypeError(`chunk's buffer must have non-zero byteLength`);
        }
        if (this._associatedReadableByteStreamController === undefined) {
            throw new TypeError('This BYOB request has been invalidated');
        }
        ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view);
    }
}
Object.defineProperties(ReadableStreamBYOBRequest.prototype, {
    respond: { enumerable: true },
    respondWithNewView: { enumerable: true },
    view: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(ReadableStreamBYOBRequest.prototype, SymbolPolyfill.toStringTag, {
        value: 'ReadableStreamBYOBRequest',
        configurable: true
    });
}
/**
 * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue.
 *
 * @public
 */
class ReadableByteStreamController {
    constructor() {
        throw new TypeError('Illegal constructor');
    }
    /**
     * Returns the current BYOB pull request, or `null` if there isn't one.
     */
    get byobRequest() {
        if (!IsReadableByteStreamController(this)) {
            throw byteStreamControllerBrandCheckException('byobRequest');
        }
        if (this._byobRequest === null && this._pendingPullIntos.length > 0) {
            const firstDescriptor = this._pendingPullIntos.peek();
            const view = new Uint8Array(firstDescriptor.buffer, firstDescriptor.byteOffset + firstDescriptor.bytesFilled, firstDescriptor.byteLength - firstDescriptor.bytesFilled);
            const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype);
            SetUpReadableStreamBYOBRequest(byobRequest, this, view);
            this._byobRequest = byobRequest;
        }
        return this._byobRequest;
    }
    /**
     * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
     * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure.
     */
    get desiredSize() {
        if (!IsReadableByteStreamController(this)) {
            throw byteStreamControllerBrandCheckException('desiredSize');
        }
        return ReadableByteStreamControllerGetDesiredSize(this);
    }
    /**
     * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
     * the stream, but once those are read, the stream will become closed.
     */
    close() {
        if (!IsReadableByteStreamController(this)) {
            throw byteStreamControllerBrandCheckException('close');
        }
        if (this._closeRequested) {
            throw new TypeError('The stream has already been closed; do not close it again!');
        }
        const state = this._controlledReadableByteStream._state;
        if (state !== 'readable') {
            throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);
        }
        ReadableByteStreamControllerClose(this);
    }
    enqueue(chunk) {
        if (!IsReadableByteStreamController(this)) {
            throw byteStreamControllerBrandCheckException('enqueue');
        }
        assertRequiredArgument(chunk, 1, 'enqueue');
        if (!ArrayBuffer.isView(chunk)) {
            throw new TypeError('chunk must be an array buffer view');
        }
        if (chunk.byteLength === 0) {
            throw new TypeError('chunk must have non-zero byteLength');
        }
        if (chunk.buffer.byteLength === 0) {
            throw new TypeError(`chunk's buffer must have non-zero byteLength`);
        }
        if (this._closeRequested) {
            throw new TypeError('stream is closed or draining');
        }
        const state = this._controlledReadableByteStream._state;
        if (state !== 'readable') {
            throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);
        }
        ReadableByteStreamControllerEnqueue(this, chunk);
    }
    /**
     * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
     */
    error(e = undefined) {
        if (!IsReadableByteStreamController(this)) {
            throw byteStreamControllerBrandCheckException('error');
        }
        ReadableByteStreamControllerError(this, e);
    }
    /** @internal */
    [CancelSteps](reason) {
        if (this._pendingPullIntos.length > 0) {
            const firstDescriptor = this._pendingPullIntos.peek();
            firstDescriptor.bytesFilled = 0;
        }
        ResetQueue(this);
        const result = this._cancelAlgorithm(reason);
        ReadableByteStreamControllerClearAlgorithms(this);
        return result;
    }
    /** @internal */
    [PullSteps](readRequest) {
        const stream = this._controlledReadableByteStream;
        if (this._queueTotalSize > 0) {
            const entry = this._queue.shift();
            this._queueTotalSize -= entry.byteLength;
            ReadableByteStreamControllerHandleQueueDrain(this);
            const view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);
            readRequest._chunkSteps(view);
            return;
        }
        const autoAllocateChunkSize = this._autoAllocateChunkSize;
        if (autoAllocateChunkSize !== undefined) {
            let buffer;
            try {
                buffer = new ArrayBuffer(autoAllocateChunkSize);
            }
            catch (bufferE) {
                readRequest._errorSteps(bufferE);
                return;
            }
            const pullIntoDescriptor = {
                buffer,
                byteOffset: 0,
                byteLength: autoAllocateChunkSize,
                bytesFilled: 0,
                elementSize: 1,
                viewConstructor: Uint8Array,
                readerType: 'default'
            };
            this._pendingPullIntos.push(pullIntoDescriptor);
        }
        ReadableStreamAddReadRequest(stream, readRequest);
        ReadableByteStreamControllerCallPullIfNeeded(this);
    }
}
Object.defineProperties(ReadableByteStreamController.prototype, {
    close: { enumerable: true },
    enqueue: { enumerable: true },
    error: { enumerable: true },
    byobRequest: { enumerable: true },
    desiredSize: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(ReadableByteStreamController.prototype, SymbolPolyfill.toStringTag, {
        value: 'ReadableByteStreamController',
        configurable: true
    });
}
// Abstract operations for the ReadableByteStreamController.
function IsReadableByteStreamController(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) {
        return false;
    }
    return true;
}
function IsReadableStreamBYOBRequest(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) {
        return false;
    }
    return true;
}
function ReadableByteStreamControllerCallPullIfNeeded(controller) {
    const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);
    if (!shouldPull) {
        return;
    }
    if (controller._pulling) {
        controller._pullAgain = true;
        return;
    }
    controller._pulling = true;
    // TODO: Test controller argument
    const pullPromise = controller._pullAlgorithm();
    uponPromise(pullPromise, () => {
        controller._pulling = false;
        if (controller._pullAgain) {
            controller._pullAgain = false;
            ReadableByteStreamControllerCallPullIfNeeded(controller);
        }
    }, e => {
        ReadableByteStreamControllerError(controller, e);
    });
}
function ReadableByteStreamControllerClearPendingPullIntos(controller) {
    ReadableByteStreamControllerInvalidateBYOBRequest(controller);
    controller._pendingPullIntos = new SimpleQueue();
}
function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor) {
    let done = false;
    if (stream._state === 'closed') {
        done = true;
    }
    const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
    if (pullIntoDescriptor.readerType === 'default') {
        ReadableStreamFulfillReadRequest(stream, filledView, done);
    }
    else {
        ReadableStreamFulfillReadIntoRequest(stream, filledView, done);
    }
}
function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) {
    const bytesFilled = pullIntoDescriptor.bytesFilled;
    const elementSize = pullIntoDescriptor.elementSize;
    return new pullIntoDescriptor.viewConstructor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize);
}
function ReadableByteStreamControllerEnqueueChunkToQueue(controller, buffer, byteOffset, byteLength) {
    controller._queue.push({ buffer, byteOffset, byteLength });
    controller._queueTotalSize += byteLength;
}
function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) {
    const elementSize = pullIntoDescriptor.elementSize;
    const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize;
    const maxBytesToCopy = Math.min(controller._queueTotalSize, pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);
    const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;
    const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize;
    let totalBytesToCopyRemaining = maxBytesToCopy;
    let ready = false;
    if (maxAlignedBytes > currentAlignedBytes) {
        totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;
        ready = true;
    }
    const queue = controller._queue;
    while (totalBytesToCopyRemaining > 0) {
        const headOfQueue = queue.peek();
        const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);
        const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
        CopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);
        if (headOfQueue.byteLength === bytesToCopy) {
            queue.shift();
        }
        else {
            headOfQueue.byteOffset += bytesToCopy;
            headOfQueue.byteLength -= bytesToCopy;
        }
        controller._queueTotalSize -= bytesToCopy;
        ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);
        totalBytesToCopyRemaining -= bytesToCopy;
    }
    return ready;
}
function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size, pullIntoDescriptor) {
    ReadableByteStreamControllerInvalidateBYOBRequest(controller);
    pullIntoDescriptor.bytesFilled += size;
}
function ReadableByteStreamControllerHandleQueueDrain(controller) {
    if (controller._queueTotalSize === 0 && controller._closeRequested) {
        ReadableByteStreamControllerClearAlgorithms(controller);
        ReadableStreamClose(controller._controlledReadableByteStream);
    }
    else {
        ReadableByteStreamControllerCallPullIfNeeded(controller);
    }
}
function ReadableByteStreamControllerInvalidateBYOBRequest(controller) {
    if (controller._byobRequest === null) {
        return;
    }
    controller._byobRequest._associatedReadableByteStreamController = undefined;
    controller._byobRequest._view = null;
    controller._byobRequest = null;
}
function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) {
    while (controller._pendingPullIntos.length > 0) {
        if (controller._queueTotalSize === 0) {
            return;
        }
        const pullIntoDescriptor = controller._pendingPullIntos.peek();
        if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
            ReadableByteStreamControllerShiftPendingPullInto(controller);
            ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
        }
    }
}
function ReadableByteStreamControllerPullInto(controller, view, readIntoRequest) {
    const stream = controller._controlledReadableByteStream;
    let elementSize = 1;
    if (view.constructor !== DataView) {
        elementSize = view.constructor.BYTES_PER_ELEMENT;
    }
    const ctor = view.constructor;
    const buffer = TransferArrayBuffer(view.buffer);
    const pullIntoDescriptor = {
        buffer,
        byteOffset: view.byteOffset,
        byteLength: view.byteLength,
        bytesFilled: 0,
        elementSize,
        viewConstructor: ctor,
        readerType: 'byob'
    };
    if (controller._pendingPullIntos.length > 0) {
        controller._pendingPullIntos.push(pullIntoDescriptor);
        // No ReadableByteStreamControllerCallPullIfNeeded() call since:
        // - No change happens on desiredSize
        // - The source has already been notified of that there's at least 1 pending read(view)
        ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
        return;
    }
    if (stream._state === 'closed') {
        const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);
        readIntoRequest._closeSteps(emptyView);
        return;
    }
    if (controller._queueTotalSize > 0) {
        if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
            const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
            ReadableByteStreamControllerHandleQueueDrain(controller);
            readIntoRequest._chunkSteps(filledView);
            return;
        }
        if (controller._closeRequested) {
            const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
            ReadableByteStreamControllerError(controller, e);
            readIntoRequest._errorSteps(e);
            return;
        }
    }
    controller._pendingPullIntos.push(pullIntoDescriptor);
    ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
    ReadableByteStreamControllerCallPullIfNeeded(controller);
}
function ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor) {
    firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);
    const stream = controller._controlledReadableByteStream;
    if (ReadableStreamHasBYOBReader(stream)) {
        while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {
            const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);
            ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);
        }
    }
}
function ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor) {
    if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength) {
        throw new RangeError('bytesWritten out of range');
    }
    ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);
    if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {
        // TODO: Figure out whether we should detach the buffer or not here.
        return;
    }
    ReadableByteStreamControllerShiftPendingPullInto(controller);
    const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;
    if (remainderSize > 0) {
        const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
        const remainder = pullIntoDescriptor.buffer.slice(end - remainderSize, end);
        ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);
    }
    pullIntoDescriptor.buffer = TransferArrayBuffer(pullIntoDescriptor.buffer);
    pullIntoDescriptor.bytesFilled -= remainderSize;
    ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
    ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
}
function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) {
    const firstDescriptor = controller._pendingPullIntos.peek();
    const state = controller._controlledReadableByteStream._state;
    if (state === 'closed') {
        if (bytesWritten !== 0) {
            throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');
        }
        ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor);
    }
    else {
        ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);
    }
    ReadableByteStreamControllerCallPullIfNeeded(controller);
}
function ReadableByteStreamControllerShiftPendingPullInto(controller) {
    const descriptor = controller._pendingPullIntos.shift();
    ReadableByteStreamControllerInvalidateBYOBRequest(controller);
    return descriptor;
}
function ReadableByteStreamControllerShouldCallPull(controller) {
    const stream = controller._controlledReadableByteStream;
    if (stream._state !== 'readable') {
        return false;
    }
    if (controller._closeRequested) {
        return false;
    }
    if (!controller._started) {
        return false;
    }
    if (ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
        return true;
    }
    if (ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0) {
        return true;
    }
    const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);
    if (desiredSize > 0) {
        return true;
    }
    return false;
}
function ReadableByteStreamControllerClearAlgorithms(controller) {
    controller._pullAlgorithm = undefined;
    controller._cancelAlgorithm = undefined;
}
// A client of ReadableByteStreamController may use these functions directly to bypass state check.
function ReadableByteStreamControllerClose(controller) {
    const stream = controller._controlledReadableByteStream;
    if (controller._closeRequested || stream._state !== 'readable') {
        return;
    }
    if (controller._queueTotalSize > 0) {
        controller._closeRequested = true;
        return;
    }
    if (controller._pendingPullIntos.length > 0) {
        const firstPendingPullInto = controller._pendingPullIntos.peek();
        if (firstPendingPullInto.bytesFilled > 0) {
            const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
            ReadableByteStreamControllerError(controller, e);
            throw e;
        }
    }
    ReadableByteStreamControllerClearAlgorithms(controller);
    ReadableStreamClose(stream);
}
function ReadableByteStreamControllerEnqueue(controller, chunk) {
    const stream = controller._controlledReadableByteStream;
    if (controller._closeRequested || stream._state !== 'readable') {
        return;
    }
    const buffer = chunk.buffer;
    const byteOffset = chunk.byteOffset;
    const byteLength = chunk.byteLength;
    const transferredBuffer = TransferArrayBuffer(buffer);
    if (ReadableStreamHasDefaultReader(stream)) {
        if (ReadableStreamGetNumReadRequests(stream) === 0) {
            ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
        }
        else {
            const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);
            ReadableStreamFulfillReadRequest(stream, transferredView, false);
        }
    }
    else if (ReadableStreamHasBYOBReader(stream)) {
        // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.
        ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
        ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
    }
    else {
        ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
    }
    ReadableByteStreamControllerCallPullIfNeeded(controller);
}
function ReadableByteStreamControllerError(controller, e) {
    const stream = controller._controlledReadableByteStream;
    if (stream._state !== 'readable') {
        return;
    }
    ReadableByteStreamControllerClearPendingPullIntos(controller);
    ResetQueue(controller);
    ReadableByteStreamControllerClearAlgorithms(controller);
    ReadableStreamError(stream, e);
}
function ReadableByteStreamControllerGetDesiredSize(controller) {
    const state = controller._controlledReadableByteStream._state;
    if (state === 'errored') {
        return null;
    }
    if (state === 'closed') {
        return 0;
    }
    return controller._strategyHWM - controller._queueTotalSize;
}
function ReadableByteStreamControllerRespond(controller, bytesWritten) {
    bytesWritten = Number(bytesWritten);
    if (!IsFiniteNonNegativeNumber(bytesWritten)) {
        throw new RangeError('bytesWritten must be a finite');
    }
    ReadableByteStreamControllerRespondInternal(controller, bytesWritten);
}
function ReadableByteStreamControllerRespondWithNewView(controller, view) {
    const firstDescriptor = controller._pendingPullIntos.peek();
    if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {
        throw new RangeError('The region specified by view does not match byobRequest');
    }
    if (firstDescriptor.byteLength !== view.byteLength) {
        throw new RangeError('The buffer of view has different capacity than byobRequest');
    }
    firstDescriptor.buffer = view.buffer;
    ReadableByteStreamControllerRespondInternal(controller, view.byteLength);
}
function SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize) {
    controller._controlledReadableByteStream = stream;
    controller._pullAgain = false;
    controller._pulling = false;
    controller._byobRequest = null;
    // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
    controller._queue = controller._queueTotalSize = undefined;
    ResetQueue(controller);
    controller._closeRequested = false;
    controller._started = false;
    controller._strategyHWM = highWaterMark;
    controller._pullAlgorithm = pullAlgorithm;
    controller._cancelAlgorithm = cancelAlgorithm;
    controller._autoAllocateChunkSize = autoAllocateChunkSize;
    controller._pendingPullIntos = new SimpleQueue();
    stream._readableStreamController = controller;
    const startResult = startAlgorithm();
    uponPromise(promiseResolvedWith(startResult), () => {
        controller._started = true;
        ReadableByteStreamControllerCallPullIfNeeded(controller);
    }, r => {
        ReadableByteStreamControllerError(controller, r);
    });
}
function SetUpReadableByteStreamControllerFromUnderlyingSource(stream, underlyingByteSource, highWaterMark) {
    const controller = Object.create(ReadableByteStreamController.prototype);
    let startAlgorithm = () => undefined;
    let pullAlgorithm = () => promiseResolvedWith(undefined);
    let cancelAlgorithm = () => promiseResolvedWith(undefined);
    if (underlyingByteSource.start !== undefined) {
        startAlgorithm = () => underlyingByteSource.start(controller);
    }
    if (underlyingByteSource.pull !== undefined) {
        pullAlgorithm = () => underlyingByteSource.pull(controller);
    }
    if (underlyingByteSource.cancel !== undefined) {
        cancelAlgorithm = reason => underlyingByteSource.cancel(reason);
    }
    const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;
    if (autoAllocateChunkSize === 0) {
        throw new TypeError('autoAllocateChunkSize must be greater than 0');
    }
    SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize);
}
function SetUpReadableStreamBYOBRequest(request, controller, view) {
    request._associatedReadableByteStreamController = controller;
    request._view = view;
}
// Helper functions for the ReadableStreamBYOBRequest.
function byobRequestBrandCheckException(name) {
    return new TypeError(`ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`);
}
// Helper functions for the ReadableByteStreamController.
function byteStreamControllerBrandCheckException(name) {
    return new TypeError(`ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`);
}

// Abstract operations for the ReadableStream.
function AcquireReadableStreamBYOBReader(stream) {
    return new ReadableStreamBYOBReader(stream);
}
// ReadableStream API exposed for controllers.
function ReadableStreamAddReadIntoRequest(stream, readIntoRequest) {
    stream._reader._readIntoRequests.push(readIntoRequest);
}
function ReadableStreamFulfillReadIntoRequest(stream, chunk, done) {
    const reader = stream._reader;
    const readIntoRequest = reader._readIntoRequests.shift();
    if (done) {
        readIntoRequest._closeSteps(chunk);
    }
    else {
        readIntoRequest._chunkSteps(chunk);
    }
}
function ReadableStreamGetNumReadIntoRequests(stream) {
    return stream._reader._readIntoRequests.length;
}
function ReadableStreamHasBYOBReader(stream) {
    const reader = stream._reader;
    if (reader === undefined) {
        return false;
    }
    if (!IsReadableStreamBYOBReader(reader)) {
        return false;
    }
    return true;
}
/**
 * A BYOB reader vended by a {@link ReadableStream}.
 *
 * @public
 */
class ReadableStreamBYOBReader {
    constructor(stream) {
        assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader');
        assertReadableStream(stream, 'First parameter');
        if (IsReadableStreamLocked(stream)) {
            throw new TypeError('This stream has already been locked for exclusive reading by another reader');
        }
        if (!IsReadableByteStreamController(stream._readableStreamController)) {
            throw new TypeError('Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' +
                'source');
        }
        ReadableStreamReaderGenericInitialize(this, stream);
        this._readIntoRequests = new SimpleQueue();
    }
    /**
     * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
     * the reader's lock is released before the stream finishes closing.
     */
    get closed() {
        if (!IsReadableStreamBYOBReader(this)) {
            return promiseRejectedWith(byobReaderBrandCheckException('closed'));
        }
        return this._closedPromise;
    }
    /**
     * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
     */
    cancel(reason = undefined) {
        if (!IsReadableStreamBYOBReader(this)) {
            return promiseRejectedWith(byobReaderBrandCheckException('cancel'));
        }
        if (this._ownerReadableStream === undefined) {
            return promiseRejectedWith(readerLockException('cancel'));
        }
        return ReadableStreamReaderGenericCancel(this, reason);
    }
    /**
     * Attempts to reads bytes into view, and returns a promise resolved with the result.
     *
     * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
     */
    read(view) {
        if (!IsReadableStreamBYOBReader(this)) {
            return promiseRejectedWith(byobReaderBrandCheckException('read'));
        }
        if (!ArrayBuffer.isView(view)) {
            return promiseRejectedWith(new TypeError('view must be an array buffer view'));
        }
        if (view.byteLength === 0) {
            return promiseRejectedWith(new TypeError('view must have non-zero byteLength'));
        }
        if (view.buffer.byteLength === 0) {
            return promiseRejectedWith(new TypeError(`view's buffer must have non-zero byteLength`));
        }
        if (this._ownerReadableStream === undefined) {
            return promiseRejectedWith(readerLockException('read from'));
        }
        let resolvePromise;
        let rejectPromise;
        const promise = newPromise((resolve, reject) => {
            resolvePromise = resolve;
            rejectPromise = reject;
        });
        const readIntoRequest = {
            _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
            _closeSteps: chunk => resolvePromise({ value: chunk, done: true }),
            _errorSteps: e => rejectPromise(e)
        };
        ReadableStreamBYOBReaderRead(this, view, readIntoRequest);
        return promise;
    }
    /**
     * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
     * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
     * from now on; otherwise, the reader will appear closed.
     *
     * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
     * the reader's {@link ReadableStreamBYOBReader.read | read()} method has not yet been settled. Attempting to
     * do so will throw a `TypeError` and leave the reader locked to the stream.
     */
    releaseLock() {
        if (!IsReadableStreamBYOBReader(this)) {
            throw byobReaderBrandCheckException('releaseLock');
        }
        if (this._ownerReadableStream === undefined) {
            return;
        }
        if (this._readIntoRequests.length > 0) {
            throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
        }
        ReadableStreamReaderGenericRelease(this);
    }
}
Object.defineProperties(ReadableStreamBYOBReader.prototype, {
    cancel: { enumerable: true },
    read: { enumerable: true },
    releaseLock: { enumerable: true },
    closed: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(ReadableStreamBYOBReader.prototype, SymbolPolyfill.toStringTag, {
        value: 'ReadableStreamBYOBReader',
        configurable: true
    });
}
// Abstract operations for the readers.
function IsReadableStreamBYOBReader(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) {
        return false;
    }
    return true;
}
function ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) {
    const stream = reader._ownerReadableStream;
    stream._disturbed = true;
    if (stream._state === 'errored') {
        readIntoRequest._errorSteps(stream._storedError);
    }
    else {
        ReadableByteStreamControllerPullInto(stream._readableStreamController, view, readIntoRequest);
    }
}
// Helper functions for the ReadableStreamBYOBReader.
function byobReaderBrandCheckException(name) {
    return new TypeError(`ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`);
}

function ExtractHighWaterMark(strategy, defaultHWM) {
    const { highWaterMark } = strategy;
    if (highWaterMark === undefined) {
        return defaultHWM;
    }
    if (NumberIsNaN(highWaterMark) || highWaterMark < 0) {
        throw new RangeError('Invalid highWaterMark');
    }
    return highWaterMark;
}
function ExtractSizeAlgorithm(strategy) {
    const { size } = strategy;
    if (!size) {
        return () => 1;
    }
    return size;
}

function convertQueuingStrategy(init, context) {
    assertDictionary(init, context);
    const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
    const size = init === null || init === void 0 ? void 0 : init.size;
    return {
        highWaterMark: highWaterMark === undefined ? undefined : convertUnrestrictedDouble(highWaterMark),
        size: size === undefined ? undefined : convertQueuingStrategySize(size, `${context} has member 'size' that`)
    };
}
function convertQueuingStrategySize(fn, context) {
    assertFunction(fn, context);
    return chunk => convertUnrestrictedDouble(fn(chunk));
}

function convertUnderlyingSink(original, context) {
    assertDictionary(original, context);
    const abort = original === null || original === void 0 ? void 0 : original.abort;
    const close = original === null || original === void 0 ? void 0 : original.close;
    const start = original === null || original === void 0 ? void 0 : original.start;
    const type = original === null || original === void 0 ? void 0 : original.type;
    const write = original === null || original === void 0 ? void 0 : original.write;
    return {
        abort: abort === undefined ?
            undefined :
            convertUnderlyingSinkAbortCallback(abort, original, `${context} has member 'abort' that`),
        close: close === undefined ?
            undefined :
            convertUnderlyingSinkCloseCallback(close, original, `${context} has member 'close' that`),
        start: start === undefined ?
            undefined :
            convertUnderlyingSinkStartCallback(start, original, `${context} has member 'start' that`),
        write: write === undefined ?
            undefined :
            convertUnderlyingSinkWriteCallback(write, original, `${context} has member 'write' that`),
        type
    };
}
function convertUnderlyingSinkAbortCallback(fn, original, context) {
    assertFunction(fn, context);
    return (reason) => promiseCall(fn, original, [reason]);
}
function convertUnderlyingSinkCloseCallback(fn, original, context) {
    assertFunction(fn, context);
    return () => promiseCall(fn, original, []);
}
function convertUnderlyingSinkStartCallback(fn, original, context) {
    assertFunction(fn, context);
    return (controller) => reflectCall(fn, original, [controller]);
}
function convertUnderlyingSinkWriteCallback(fn, original, context) {
    assertFunction(fn, context);
    return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
}

function assertWritableStream(x, context) {
    if (!IsWritableStream(x)) {
        throw new TypeError(`${context} is not a WritableStream.`);
    }
}

/**
 * A writable stream represents a destination for data, into which you can write.
 *
 * @public
 */
class WritableStream$1 {
    constructor(rawUnderlyingSink = {}, rawStrategy = {}) {
        if (rawUnderlyingSink === undefined) {
            rawUnderlyingSink = null;
        }
        else {
            assertObject(rawUnderlyingSink, 'First parameter');
        }
        const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
        const underlyingSink = convertUnderlyingSink(rawUnderlyingSink, 'First parameter');
        InitializeWritableStream(this);
        const type = underlyingSink.type;
        if (type !== undefined) {
            throw new RangeError('Invalid type is specified');
        }
        const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
        const highWaterMark = ExtractHighWaterMark(strategy, 1);
        SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, highWaterMark, sizeAlgorithm);
    }
    /**
     * Returns whether or not the writable stream is locked to a writer.
     */
    get locked() {
        if (!IsWritableStream(this)) {
            throw streamBrandCheckException$2('locked');
        }
        return IsWritableStreamLocked(this);
    }
    /**
     * Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be
     * immediately moved to an errored state, with any queued-up writes discarded. This will also execute any abort
     * mechanism of the underlying sink.
     *
     * The returned promise will fulfill if the stream shuts down successfully, or reject if the underlying sink signaled
     * that there was an error doing so. Additionally, it will reject with a `TypeError` (without attempting to cancel
     * the stream) if the stream is currently locked.
     */
    abort(reason = undefined) {
        if (!IsWritableStream(this)) {
            return promiseRejectedWith(streamBrandCheckException$2('abort'));
        }
        if (IsWritableStreamLocked(this)) {
            return promiseRejectedWith(new TypeError('Cannot abort a stream that already has a writer'));
        }
        return WritableStreamAbort(this, reason);
    }
    /**
     * Closes the stream. The underlying sink will finish processing any previously-written chunks, before invoking its
     * close behavior. During this time any further attempts to write will fail (without erroring the stream).
     *
     * The method returns a promise that will fulfill if all remaining chunks are successfully written and the stream
     * successfully closes, or rejects if an error is encountered during this process. Additionally, it will reject with
     * a `TypeError` (without attempting to cancel the stream) if the stream is currently locked.
     */
    close() {
        if (!IsWritableStream(this)) {
            return promiseRejectedWith(streamBrandCheckException$2('close'));
        }
        if (IsWritableStreamLocked(this)) {
            return promiseRejectedWith(new TypeError('Cannot close a stream that already has a writer'));
        }
        if (WritableStreamCloseQueuedOrInFlight(this)) {
            return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
        }
        return WritableStreamClose(this);
    }
    /**
     * Creates a {@link WritableStreamDefaultWriter | writer} and locks the stream to the new writer. While the stream
     * is locked, no other writer can be acquired until this one is released.
     *
     * This functionality is especially useful for creating abstractions that desire the ability to write to a stream
     * without interruption or interleaving. By getting a writer for the stream, you can ensure nobody else can write at
     * the same time, which would cause the resulting written data to be unpredictable and probably useless.
     */
    getWriter() {
        if (!IsWritableStream(this)) {
            throw streamBrandCheckException$2('getWriter');
        }
        return AcquireWritableStreamDefaultWriter(this);
    }
}
Object.defineProperties(WritableStream$1.prototype, {
    abort: { enumerable: true },
    close: { enumerable: true },
    getWriter: { enumerable: true },
    locked: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(WritableStream$1.prototype, SymbolPolyfill.toStringTag, {
        value: 'WritableStream',
        configurable: true
    });
}
// Abstract operations for the WritableStream.
function AcquireWritableStreamDefaultWriter(stream) {
    return new WritableStreamDefaultWriter(stream);
}
// Throws if and only if startAlgorithm throws.
function CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
    const stream = Object.create(WritableStream$1.prototype);
    InitializeWritableStream(stream);
    const controller = Object.create(WritableStreamDefaultController.prototype);
    SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
    return stream;
}
function InitializeWritableStream(stream) {
    stream._state = 'writable';
    // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is
    // 'erroring' or 'errored'. May be set to an undefined value.
    stream._storedError = undefined;
    stream._writer = undefined;
    // Initialize to undefined first because the constructor of the controller checks this
    // variable to validate the caller.
    stream._writableStreamController = undefined;
    // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data
    // producer without waiting for the queued writes to finish.
    stream._writeRequests = new SimpleQueue();
    // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents
    // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here.
    stream._inFlightWriteRequest = undefined;
    // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer
    // has been detached.
    stream._closeRequest = undefined;
    // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it
    // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here.
    stream._inFlightCloseRequest = undefined;
    // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached.
    stream._pendingAbortRequest = undefined;
    // The backpressure signal set by the controller.
    stream._backpressure = false;
}
function IsWritableStream(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) {
        return false;
    }
    return true;
}
function IsWritableStreamLocked(stream) {
    if (stream._writer === undefined) {
        return false;
    }
    return true;
}
function WritableStreamAbort(stream, reason) {
    const state = stream._state;
    if (state === 'closed' || state === 'errored') {
        return promiseResolvedWith(undefined);
    }
    if (stream._pendingAbortRequest !== undefined) {
        return stream._pendingAbortRequest._promise;
    }
    let wasAlreadyErroring = false;
    if (state === 'erroring') {
        wasAlreadyErroring = true;
        // reason will not be used, so don't keep a reference to it.
        reason = undefined;
    }
    const promise = newPromise((resolve, reject) => {
        stream._pendingAbortRequest = {
            _promise: undefined,
            _resolve: resolve,
            _reject: reject,
            _reason: reason,
            _wasAlreadyErroring: wasAlreadyErroring
        };
    });
    stream._pendingAbortRequest._promise = promise;
    if (!wasAlreadyErroring) {
        WritableStreamStartErroring(stream, reason);
    }
    return promise;
}
function WritableStreamClose(stream) {
    const state = stream._state;
    if (state === 'closed' || state === 'errored') {
        return promiseRejectedWith(new TypeError(`The stream (in ${state} state) is not in the writable state and cannot be closed`));
    }
    const promise = newPromise((resolve, reject) => {
        const closeRequest = {
            _resolve: resolve,
            _reject: reject
        };
        stream._closeRequest = closeRequest;
    });
    const writer = stream._writer;
    if (writer !== undefined && stream._backpressure && state === 'writable') {
        defaultWriterReadyPromiseResolve(writer);
    }
    WritableStreamDefaultControllerClose(stream._writableStreamController);
    return promise;
}
// WritableStream API exposed for controllers.
function WritableStreamAddWriteRequest(stream) {
    const promise = newPromise((resolve, reject) => {
        const writeRequest = {
            _resolve: resolve,
            _reject: reject
        };
        stream._writeRequests.push(writeRequest);
    });
    return promise;
}
function WritableStreamDealWithRejection(stream, error) {
    const state = stream._state;
    if (state === 'writable') {
        WritableStreamStartErroring(stream, error);
        return;
    }
    WritableStreamFinishErroring(stream);
}
function WritableStreamStartErroring(stream, reason) {
    const controller = stream._writableStreamController;
    stream._state = 'erroring';
    stream._storedError = reason;
    const writer = stream._writer;
    if (writer !== undefined) {
        WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason);
    }
    if (!WritableStreamHasOperationMarkedInFlight(stream) && controller._started) {
        WritableStreamFinishErroring(stream);
    }
}
function WritableStreamFinishErroring(stream) {
    stream._state = 'errored';
    stream._writableStreamController[ErrorSteps]();
    const storedError = stream._storedError;
    stream._writeRequests.forEach(writeRequest => {
        writeRequest._reject(storedError);
    });
    stream._writeRequests = new SimpleQueue();
    if (stream._pendingAbortRequest === undefined) {
        WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
        return;
    }
    const abortRequest = stream._pendingAbortRequest;
    stream._pendingAbortRequest = undefined;
    if (abortRequest._wasAlreadyErroring) {
        abortRequest._reject(storedError);
        WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
        return;
    }
    const promise = stream._writableStreamController[AbortSteps](abortRequest._reason);
    uponPromise(promise, () => {
        abortRequest._resolve();
        WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
    }, (reason) => {
        abortRequest._reject(reason);
        WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
    });
}
function WritableStreamFinishInFlightWrite(stream) {
    stream._inFlightWriteRequest._resolve(undefined);
    stream._inFlightWriteRequest = undefined;
}
function WritableStreamFinishInFlightWriteWithError(stream, error) {
    stream._inFlightWriteRequest._reject(error);
    stream._inFlightWriteRequest = undefined;
    WritableStreamDealWithRejection(stream, error);
}
function WritableStreamFinishInFlightClose(stream) {
    stream._inFlightCloseRequest._resolve(undefined);
    stream._inFlightCloseRequest = undefined;
    const state = stream._state;
    if (state === 'erroring') {
        // The error was too late to do anything, so it is ignored.
        stream._storedError = undefined;
        if (stream._pendingAbortRequest !== undefined) {
            stream._pendingAbortRequest._resolve();
            stream._pendingAbortRequest = undefined;
        }
    }
    stream._state = 'closed';
    const writer = stream._writer;
    if (writer !== undefined) {
        defaultWriterClosedPromiseResolve(writer);
    }
}
function WritableStreamFinishInFlightCloseWithError(stream, error) {
    stream._inFlightCloseRequest._reject(error);
    stream._inFlightCloseRequest = undefined;
    // Never execute sink abort() after sink close().
    if (stream._pendingAbortRequest !== undefined) {
        stream._pendingAbortRequest._reject(error);
        stream._pendingAbortRequest = undefined;
    }
    WritableStreamDealWithRejection(stream, error);
}
// TODO(ricea): Fix alphabetical order.
function WritableStreamCloseQueuedOrInFlight(stream) {
    if (stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined) {
        return false;
    }
    return true;
}
function WritableStreamHasOperationMarkedInFlight(stream) {
    if (stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined) {
        return false;
    }
    return true;
}
function WritableStreamMarkCloseRequestInFlight(stream) {
    stream._inFlightCloseRequest = stream._closeRequest;
    stream._closeRequest = undefined;
}
function WritableStreamMarkFirstWriteRequestInFlight(stream) {
    stream._inFlightWriteRequest = stream._writeRequests.shift();
}
function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) {
    if (stream._closeRequest !== undefined) {
        stream._closeRequest._reject(stream._storedError);
        stream._closeRequest = undefined;
    }
    const writer = stream._writer;
    if (writer !== undefined) {
        defaultWriterClosedPromiseReject(writer, stream._storedError);
    }
}
function WritableStreamUpdateBackpressure(stream, backpressure) {
    const writer = stream._writer;
    if (writer !== undefined && backpressure !== stream._backpressure) {
        if (backpressure) {
            defaultWriterReadyPromiseReset(writer);
        }
        else {
            defaultWriterReadyPromiseResolve(writer);
        }
    }
    stream._backpressure = backpressure;
}
/**
 * A default writer vended by a {@link WritableStream}.
 *
 * @public
 */
class WritableStreamDefaultWriter {
    constructor(stream) {
        assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter');
        assertWritableStream(stream, 'First parameter');
        if (IsWritableStreamLocked(stream)) {
            throw new TypeError('This stream has already been locked for exclusive writing by another writer');
        }
        this._ownerWritableStream = stream;
        stream._writer = this;
        const state = stream._state;
        if (state === 'writable') {
            if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._backpressure) {
                defaultWriterReadyPromiseInitialize(this);
            }
            else {
                defaultWriterReadyPromiseInitializeAsResolved(this);
            }
            defaultWriterClosedPromiseInitialize(this);
        }
        else if (state === 'erroring') {
            defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError);
            defaultWriterClosedPromiseInitialize(this);
        }
        else if (state === 'closed') {
            defaultWriterReadyPromiseInitializeAsResolved(this);
            defaultWriterClosedPromiseInitializeAsResolved(this);
        }
        else {
            const storedError = stream._storedError;
            defaultWriterReadyPromiseInitializeAsRejected(this, storedError);
            defaultWriterClosedPromiseInitializeAsRejected(this, storedError);
        }
    }
    /**
     * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
     * the writer’s lock is released before the stream finishes closing.
     */
    get closed() {
        if (!IsWritableStreamDefaultWriter(this)) {
            return promiseRejectedWith(defaultWriterBrandCheckException('closed'));
        }
        return this._closedPromise;
    }
    /**
     * Returns the desired size to fill the stream’s internal queue. It can be negative, if the queue is over-full.
     * A producer can use this information to determine the right amount of data to write.
     *
     * It will be `null` if the stream cannot be successfully written to (due to either being errored, or having an abort
     * queued up). It will return zero if the stream is closed. And the getter will throw an exception if invoked when
     * the writer’s lock is released.
     */
    get desiredSize() {
        if (!IsWritableStreamDefaultWriter(this)) {
            throw defaultWriterBrandCheckException('desiredSize');
        }
        if (this._ownerWritableStream === undefined) {
            throw defaultWriterLockException('desiredSize');
        }
        return WritableStreamDefaultWriterGetDesiredSize(this);
    }
    /**
     * Returns a promise that will be fulfilled when the desired size to fill the stream’s internal queue transitions
     * from non-positive to positive, signaling that it is no longer applying backpressure. Once the desired size dips
     * back to zero or below, the getter will return a new promise that stays pending until the next transition.
     *
     * If the stream becomes errored or aborted, or the writer’s lock is released, the returned promise will become
     * rejected.
     */
    get ready() {
        if (!IsWritableStreamDefaultWriter(this)) {
            return promiseRejectedWith(defaultWriterBrandCheckException('ready'));
        }
        return this._readyPromise;
    }
    /**
     * If the reader is active, behaves the same as {@link WritableStream.abort | stream.abort(reason)}.
     */
    abort(reason = undefined) {
        if (!IsWritableStreamDefaultWriter(this)) {
            return promiseRejectedWith(defaultWriterBrandCheckException('abort'));
        }
        if (this._ownerWritableStream === undefined) {
            return promiseRejectedWith(defaultWriterLockException('abort'));
        }
        return WritableStreamDefaultWriterAbort(this, reason);
    }
    /**
     * If the reader is active, behaves the same as {@link WritableStream.close | stream.close()}.
     */
    close() {
        if (!IsWritableStreamDefaultWriter(this)) {
            return promiseRejectedWith(defaultWriterBrandCheckException('close'));
        }
        const stream = this._ownerWritableStream;
        if (stream === undefined) {
            return promiseRejectedWith(defaultWriterLockException('close'));
        }
        if (WritableStreamCloseQueuedOrInFlight(stream)) {
            return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
        }
        return WritableStreamDefaultWriterClose(this);
    }
    /**
     * Releases the writer’s lock on the corresponding stream. After the lock is released, the writer is no longer active.
     * If the associated stream is errored when the lock is released, the writer will appear errored in the same way from
     * now on; otherwise, the writer will appear closed.
     *
     * Note that the lock can still be released even if some ongoing writes have not yet finished (i.e. even if the
     * promises returned from previous calls to {@link WritableStreamDefaultWriter.write | write()} have not yet settled).
     * It’s not necessary to hold the lock on the writer for the duration of the write; the lock instead simply prevents
     * other producers from writing in an interleaved manner.
     */
    releaseLock() {
        if (!IsWritableStreamDefaultWriter(this)) {
            throw defaultWriterBrandCheckException('releaseLock');
        }
        const stream = this._ownerWritableStream;
        if (stream === undefined) {
            return;
        }
        WritableStreamDefaultWriterRelease(this);
    }
    write(chunk = undefined) {
        if (!IsWritableStreamDefaultWriter(this)) {
            return promiseRejectedWith(defaultWriterBrandCheckException('write'));
        }
        if (this._ownerWritableStream === undefined) {
            return promiseRejectedWith(defaultWriterLockException('write to'));
        }
        return WritableStreamDefaultWriterWrite(this, chunk);
    }
}
Object.defineProperties(WritableStreamDefaultWriter.prototype, {
    abort: { enumerable: true },
    close: { enumerable: true },
    releaseLock: { enumerable: true },
    write: { enumerable: true },
    closed: { enumerable: true },
    desiredSize: { enumerable: true },
    ready: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(WritableStreamDefaultWriter.prototype, SymbolPolyfill.toStringTag, {
        value: 'WritableStreamDefaultWriter',
        configurable: true
    });
}
// Abstract operations for the WritableStreamDefaultWriter.
function IsWritableStreamDefaultWriter(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) {
        return false;
    }
    return true;
}
// A client of WritableStreamDefaultWriter may use these functions directly to bypass state check.
function WritableStreamDefaultWriterAbort(writer, reason) {
    const stream = writer._ownerWritableStream;
    return WritableStreamAbort(stream, reason);
}
function WritableStreamDefaultWriterClose(writer) {
    const stream = writer._ownerWritableStream;
    return WritableStreamClose(stream);
}
function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) {
    const stream = writer._ownerWritableStream;
    const state = stream._state;
    if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
        return promiseResolvedWith(undefined);
    }
    if (state === 'errored') {
        return promiseRejectedWith(stream._storedError);
    }
    return WritableStreamDefaultWriterClose(writer);
}
function WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) {
    if (writer._closedPromiseState === 'pending') {
        defaultWriterClosedPromiseReject(writer, error);
    }
    else {
        defaultWriterClosedPromiseResetToRejected(writer, error);
    }
}
function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) {
    if (writer._readyPromiseState === 'pending') {
        defaultWriterReadyPromiseReject(writer, error);
    }
    else {
        defaultWriterReadyPromiseResetToRejected(writer, error);
    }
}
function WritableStreamDefaultWriterGetDesiredSize(writer) {
    const stream = writer._ownerWritableStream;
    const state = stream._state;
    if (state === 'errored' || state === 'erroring') {
        return null;
    }
    if (state === 'closed') {
        return 0;
    }
    return WritableStreamDefaultControllerGetDesiredSize(stream._writableStreamController);
}
function WritableStreamDefaultWriterRelease(writer) {
    const stream = writer._ownerWritableStream;
    const releasedError = new TypeError(`Writer was released and can no longer be used to monitor the stream's closedness`);
    WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
    // The state transitions to "errored" before the sink abort() method runs, but the writer.closed promise is not
    // rejected until afterwards. This means that simply testing state will not work.
    WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
    stream._writer = undefined;
    writer._ownerWritableStream = undefined;
}
function WritableStreamDefaultWriterWrite(writer, chunk) {
    const stream = writer._ownerWritableStream;
    const controller = stream._writableStreamController;
    const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk);
    if (stream !== writer._ownerWritableStream) {
        return promiseRejectedWith(defaultWriterLockException('write to'));
    }
    const state = stream._state;
    if (state === 'errored') {
        return promiseRejectedWith(stream._storedError);
    }
    if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
        return promiseRejectedWith(new TypeError('The stream is closing or closed and cannot be written to'));
    }
    if (state === 'erroring') {
        return promiseRejectedWith(stream._storedError);
    }
    const promise = WritableStreamAddWriteRequest(stream);
    WritableStreamDefaultControllerWrite(controller, chunk, chunkSize);
    return promise;
}
const closeSentinel = {};
/**
 * Allows control of a {@link WritableStream | writable stream}'s state and internal queue.
 *
 * @public
 */
class WritableStreamDefaultController {
    constructor() {
        throw new TypeError('Illegal constructor');
    }
    /**
     * Closes the controlled writable stream, making all future interactions with it fail with the given error `e`.
     *
     * This method is rarely used, since usually it suffices to return a rejected promise from one of the underlying
     * sink's methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the
     * normal lifecycle of interactions with the underlying sink.
     */
    error(e = undefined) {
        if (!IsWritableStreamDefaultController(this)) {
            throw new TypeError('WritableStreamDefaultController.prototype.error can only be used on a WritableStreamDefaultController');
        }
        const state = this._controlledWritableStream._state;
        if (state !== 'writable') {
            // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so
            // just treat it as a no-op.
            return;
        }
        WritableStreamDefaultControllerError(this, e);
    }
    /** @internal */
    [AbortSteps](reason) {
        const result = this._abortAlgorithm(reason);
        WritableStreamDefaultControllerClearAlgorithms(this);
        return result;
    }
    /** @internal */
    [ErrorSteps]() {
        ResetQueue(this);
    }
}
Object.defineProperties(WritableStreamDefaultController.prototype, {
    error: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(WritableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
        value: 'WritableStreamDefaultController',
        configurable: true
    });
}
// Abstract operations implementing interface required by the WritableStream.
function IsWritableStreamDefaultController(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) {
        return false;
    }
    return true;
}
function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) {
    controller._controlledWritableStream = stream;
    stream._writableStreamController = controller;
    // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
    controller._queue = undefined;
    controller._queueTotalSize = undefined;
    ResetQueue(controller);
    controller._started = false;
    controller._strategySizeAlgorithm = sizeAlgorithm;
    controller._strategyHWM = highWaterMark;
    controller._writeAlgorithm = writeAlgorithm;
    controller._closeAlgorithm = closeAlgorithm;
    controller._abortAlgorithm = abortAlgorithm;
    const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
    WritableStreamUpdateBackpressure(stream, backpressure);
    const startResult = startAlgorithm();
    const startPromise = promiseResolvedWith(startResult);
    uponPromise(startPromise, () => {
        controller._started = true;
        WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
    }, r => {
        controller._started = true;
        WritableStreamDealWithRejection(stream, r);
    });
}
function SetUpWritableStreamDefaultControllerFromUnderlyingSink(stream, underlyingSink, highWaterMark, sizeAlgorithm) {
    const controller = Object.create(WritableStreamDefaultController.prototype);
    let startAlgorithm = () => undefined;
    let writeAlgorithm = () => promiseResolvedWith(undefined);
    let closeAlgorithm = () => promiseResolvedWith(undefined);
    let abortAlgorithm = () => promiseResolvedWith(undefined);
    if (underlyingSink.start !== undefined) {
        startAlgorithm = () => underlyingSink.start(controller);
    }
    if (underlyingSink.write !== undefined) {
        writeAlgorithm = chunk => underlyingSink.write(chunk, controller);
    }
    if (underlyingSink.close !== undefined) {
        closeAlgorithm = () => underlyingSink.close();
    }
    if (underlyingSink.abort !== undefined) {
        abortAlgorithm = reason => underlyingSink.abort(reason);
    }
    SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
}
// ClearAlgorithms may be called twice. Erroring the same stream in multiple ways will often result in redundant calls.
function WritableStreamDefaultControllerClearAlgorithms(controller) {
    controller._writeAlgorithm = undefined;
    controller._closeAlgorithm = undefined;
    controller._abortAlgorithm = undefined;
    controller._strategySizeAlgorithm = undefined;
}
function WritableStreamDefaultControllerClose(controller) {
    EnqueueValueWithSize(controller, closeSentinel, 0);
    WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
}
function WritableStreamDefaultControllerGetChunkSize(controller, chunk) {
    try {
        return controller._strategySizeAlgorithm(chunk);
    }
    catch (chunkSizeE) {
        WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE);
        return 1;
    }
}
function WritableStreamDefaultControllerGetDesiredSize(controller) {
    return controller._strategyHWM - controller._queueTotalSize;
}
function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) {
    try {
        EnqueueValueWithSize(controller, chunk, chunkSize);
    }
    catch (enqueueE) {
        WritableStreamDefaultControllerErrorIfNeeded(controller, enqueueE);
        return;
    }
    const stream = controller._controlledWritableStream;
    if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._state === 'writable') {
        const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
        WritableStreamUpdateBackpressure(stream, backpressure);
    }
    WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
}
// Abstract operations for the WritableStreamDefaultController.
function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) {
    const stream = controller._controlledWritableStream;
    if (!controller._started) {
        return;
    }
    if (stream._inFlightWriteRequest !== undefined) {
        return;
    }
    const state = stream._state;
    if (state === 'erroring') {
        WritableStreamFinishErroring(stream);
        return;
    }
    if (controller._queue.length === 0) {
        return;
    }
    const value = PeekQueueValue(controller);
    if (value === closeSentinel) {
        WritableStreamDefaultControllerProcessClose(controller);
    }
    else {
        WritableStreamDefaultControllerProcessWrite(controller, value);
    }
}
function WritableStreamDefaultControllerErrorIfNeeded(controller, error) {
    if (controller._controlledWritableStream._state === 'writable') {
        WritableStreamDefaultControllerError(controller, error);
    }
}
function WritableStreamDefaultControllerProcessClose(controller) {
    const stream = controller._controlledWritableStream;
    WritableStreamMarkCloseRequestInFlight(stream);
    DequeueValue(controller);
    const sinkClosePromise = controller._closeAlgorithm();
    WritableStreamDefaultControllerClearAlgorithms(controller);
    uponPromise(sinkClosePromise, () => {
        WritableStreamFinishInFlightClose(stream);
    }, reason => {
        WritableStreamFinishInFlightCloseWithError(stream, reason);
    });
}
function WritableStreamDefaultControllerProcessWrite(controller, chunk) {
    const stream = controller._controlledWritableStream;
    WritableStreamMarkFirstWriteRequestInFlight(stream);
    const sinkWritePromise = controller._writeAlgorithm(chunk);
    uponPromise(sinkWritePromise, () => {
        WritableStreamFinishInFlightWrite(stream);
        const state = stream._state;
        DequeueValue(controller);
        if (!WritableStreamCloseQueuedOrInFlight(stream) && state === 'writable') {
            const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
            WritableStreamUpdateBackpressure(stream, backpressure);
        }
        WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
    }, reason => {
        if (stream._state === 'writable') {
            WritableStreamDefaultControllerClearAlgorithms(controller);
        }
        WritableStreamFinishInFlightWriteWithError(stream, reason);
    });
}
function WritableStreamDefaultControllerGetBackpressure(controller) {
    const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller);
    return desiredSize <= 0;
}
// A client of WritableStreamDefaultController may use these functions directly to bypass state check.
function WritableStreamDefaultControllerError(controller, error) {
    const stream = controller._controlledWritableStream;
    WritableStreamDefaultControllerClearAlgorithms(controller);
    WritableStreamStartErroring(stream, error);
}
// Helper functions for the WritableStream.
function streamBrandCheckException$2(name) {
    return new TypeError(`WritableStream.prototype.${name} can only be used on a WritableStream`);
}
// Helper functions for the WritableStreamDefaultWriter.
function defaultWriterBrandCheckException(name) {
    return new TypeError(`WritableStreamDefaultWriter.prototype.${name} can only be used on a WritableStreamDefaultWriter`);
}
function defaultWriterLockException(name) {
    return new TypeError('Cannot ' + name + ' a stream using a released writer');
}
function defaultWriterClosedPromiseInitialize(writer) {
    writer._closedPromise = newPromise((resolve, reject) => {
        writer._closedPromise_resolve = resolve;
        writer._closedPromise_reject = reject;
        writer._closedPromiseState = 'pending';
    });
}
function defaultWriterClosedPromiseInitializeAsRejected(writer, reason) {
    defaultWriterClosedPromiseInitialize(writer);
    defaultWriterClosedPromiseReject(writer, reason);
}
function defaultWriterClosedPromiseInitializeAsResolved(writer) {
    defaultWriterClosedPromiseInitialize(writer);
    defaultWriterClosedPromiseResolve(writer);
}
function defaultWriterClosedPromiseReject(writer, reason) {
    if (writer._closedPromise_reject === undefined) {
        return;
    }
    setPromiseIsHandledToTrue(writer._closedPromise);
    writer._closedPromise_reject(reason);
    writer._closedPromise_resolve = undefined;
    writer._closedPromise_reject = undefined;
    writer._closedPromiseState = 'rejected';
}
function defaultWriterClosedPromiseResetToRejected(writer, reason) {
    defaultWriterClosedPromiseInitializeAsRejected(writer, reason);
}
function defaultWriterClosedPromiseResolve(writer) {
    if (writer._closedPromise_resolve === undefined) {
        return;
    }
    writer._closedPromise_resolve(undefined);
    writer._closedPromise_resolve = undefined;
    writer._closedPromise_reject = undefined;
    writer._closedPromiseState = 'resolved';
}
function defaultWriterReadyPromiseInitialize(writer) {
    writer._readyPromise = newPromise((resolve, reject) => {
        writer._readyPromise_resolve = resolve;
        writer._readyPromise_reject = reject;
    });
    writer._readyPromiseState = 'pending';
}
function defaultWriterReadyPromiseInitializeAsRejected(writer, reason) {
    defaultWriterReadyPromiseInitialize(writer);
    defaultWriterReadyPromiseReject(writer, reason);
}
function defaultWriterReadyPromiseInitializeAsResolved(writer) {
    defaultWriterReadyPromiseInitialize(writer);
    defaultWriterReadyPromiseResolve(writer);
}
function defaultWriterReadyPromiseReject(writer, reason) {
    if (writer._readyPromise_reject === undefined) {
        return;
    }
    setPromiseIsHandledToTrue(writer._readyPromise);
    writer._readyPromise_reject(reason);
    writer._readyPromise_resolve = undefined;
    writer._readyPromise_reject = undefined;
    writer._readyPromiseState = 'rejected';
}
function defaultWriterReadyPromiseReset(writer) {
    defaultWriterReadyPromiseInitialize(writer);
}
function defaultWriterReadyPromiseResetToRejected(writer, reason) {
    defaultWriterReadyPromiseInitializeAsRejected(writer, reason);
}
function defaultWriterReadyPromiseResolve(writer) {
    if (writer._readyPromise_resolve === undefined) {
        return;
    }
    writer._readyPromise_resolve(undefined);
    writer._readyPromise_resolve = undefined;
    writer._readyPromise_reject = undefined;
    writer._readyPromiseState = 'fulfilled';
}

function isAbortSignal(value) {
    if (typeof value !== 'object' || value === null) {
        return false;
    }
    try {
        return typeof value.aborted === 'boolean';
    }
    catch (_a) {
        // AbortSignal.prototype.aborted throws if its brand check fails
        return false;
    }
}

/// <reference lib="dom" />
const NativeDOMException = typeof DOMException !== 'undefined' ? DOMException : undefined;

/// <reference types="node" />
function isDOMExceptionConstructor(ctor) {
    if (!(typeof ctor === 'function' || typeof ctor === 'object')) {
        return false;
    }
    try {
        new ctor();
        return true;
    }
    catch (_a) {
        return false;
    }
}
function createDOMExceptionPolyfill() {
    // eslint-disable-next-line no-shadow
    const ctor = function DOMException(message, name) {
        this.message = message || '';
        this.name = name || 'Error';
        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, this.constructor);
        }
    };
    ctor.prototype = Object.create(Error.prototype);
    Object.defineProperty(ctor.prototype, 'constructor', { value: ctor, writable: true, configurable: true });
    return ctor;
}
// eslint-disable-next-line no-redeclare
const DOMException$1 = isDOMExceptionConstructor(NativeDOMException) ? NativeDOMException : createDOMExceptionPolyfill();

function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventCancel, signal) {
    const reader = AcquireReadableStreamDefaultReader(source);
    const writer = AcquireWritableStreamDefaultWriter(dest);
    source._disturbed = true;
    let shuttingDown = false;
    // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown.
    let currentWrite = promiseResolvedWith(undefined);
    return newPromise((resolve, reject) => {
        let abortAlgorithm;
        if (signal !== undefined) {
            abortAlgorithm = () => {
                const error = new DOMException$1('Aborted', 'AbortError');
                const actions = [];
                if (!preventAbort) {
                    actions.push(() => {
                        if (dest._state === 'writable') {
                            return WritableStreamAbort(dest, error);
                        }
                        return promiseResolvedWith(undefined);
                    });
                }
                if (!preventCancel) {
                    actions.push(() => {
                        if (source._state === 'readable') {
                            return ReadableStreamCancel(source, error);
                        }
                        return promiseResolvedWith(undefined);
                    });
                }
                shutdownWithAction(() => Promise.all(actions.map(action => action())), true, error);
            };
            if (signal.aborted) {
                abortAlgorithm();
                return;
            }
            signal.addEventListener('abort', abortAlgorithm);
        }
        // Using reader and writer, read all chunks from this and write them to dest
        // - Backpressure must be enforced
        // - Shutdown must stop all activity
        function pipeLoop() {
            return newPromise((resolveLoop, rejectLoop) => {
                function next(done) {
                    if (done) {
                        resolveLoop();
                    }
                    else {
                        // Use `PerformPromiseThen` instead of `uponPromise` to avoid
                        // adding unnecessary `.catch(rethrowAssertionErrorRejection)` handlers
                        PerformPromiseThen(pipeStep(), next, rejectLoop);
                    }
                }
                next(false);
            });
        }
        function pipeStep() {
            if (shuttingDown) {
                return promiseResolvedWith(true);
            }
            return PerformPromiseThen(writer._readyPromise, () => {
                return newPromise((resolveRead, rejectRead) => {
                    ReadableStreamDefaultReaderRead(reader, {
                        _chunkSteps: chunk => {
                            currentWrite = PerformPromiseThen(WritableStreamDefaultWriterWrite(writer, chunk), undefined, noop);
                            resolveRead(false);
                        },
                        _closeSteps: () => resolveRead(true),
                        _errorSteps: rejectRead
                    });
                });
            });
        }
        // Errors must be propagated forward
        isOrBecomesErrored(source, reader._closedPromise, storedError => {
            if (!preventAbort) {
                shutdownWithAction(() => WritableStreamAbort(dest, storedError), true, storedError);
            }
            else {
                shutdown(true, storedError);
            }
        });
        // Errors must be propagated backward
        isOrBecomesErrored(dest, writer._closedPromise, storedError => {
            if (!preventCancel) {
                shutdownWithAction(() => ReadableStreamCancel(source, storedError), true, storedError);
            }
            else {
                shutdown(true, storedError);
            }
        });
        // Closing must be propagated forward
        isOrBecomesClosed(source, reader._closedPromise, () => {
            if (!preventClose) {
                shutdownWithAction(() => WritableStreamDefaultWriterCloseWithErrorPropagation(writer));
            }
            else {
                shutdown();
            }
        });
        // Closing must be propagated backward
        if (WritableStreamCloseQueuedOrInFlight(dest) || dest._state === 'closed') {
            const destClosed = new TypeError('the destination writable stream closed before all data could be piped to it');
            if (!preventCancel) {
                shutdownWithAction(() => ReadableStreamCancel(source, destClosed), true, destClosed);
            }
            else {
                shutdown(true, destClosed);
            }
        }
        setPromiseIsHandledToTrue(pipeLoop());
        function waitForWritesToFinish() {
            // Another write may have started while we were waiting on this currentWrite, so we have to be sure to wait
            // for that too.
            const oldCurrentWrite = currentWrite;
            return PerformPromiseThen(currentWrite, () => oldCurrentWrite !== currentWrite ? waitForWritesToFinish() : undefined);
        }
        function isOrBecomesErrored(stream, promise, action) {
            if (stream._state === 'errored') {
                action(stream._storedError);
            }
            else {
                uponRejection(promise, action);
            }
        }
        function isOrBecomesClosed(stream, promise, action) {
            if (stream._state === 'closed') {
                action();
            }
            else {
                uponFulfillment(promise, action);
            }
        }
        function shutdownWithAction(action, originalIsError, originalError) {
            if (shuttingDown) {
                return;
            }
            shuttingDown = true;
            if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
                uponFulfillment(waitForWritesToFinish(), doTheRest);
            }
            else {
                doTheRest();
            }
            function doTheRest() {
                uponPromise(action(), () => finalize(originalIsError, originalError), newError => finalize(true, newError));
            }
        }
        function shutdown(isError, error) {
            if (shuttingDown) {
                return;
            }
            shuttingDown = true;
            if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
                uponFulfillment(waitForWritesToFinish(), () => finalize(isError, error));
            }
            else {
                finalize(isError, error);
            }
        }
        function finalize(isError, error) {
            WritableStreamDefaultWriterRelease(writer);
            ReadableStreamReaderGenericRelease(reader);
            if (signal !== undefined) {
                signal.removeEventListener('abort', abortAlgorithm);
            }
            if (isError) {
                reject(error);
            }
            else {
                resolve(undefined);
            }
        }
    });
}

/**
 * Allows control of a {@link ReadableStream | readable stream}'s state and internal queue.
 *
 * @public
 */
class ReadableStreamDefaultController {
    constructor() {
        throw new TypeError('Illegal constructor');
    }
    /**
     * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
     * over-full. An underlying source ought to use this information to determine when and how to apply backpressure.
     */
    get desiredSize() {
        if (!IsReadableStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException$1('desiredSize');
        }
        return ReadableStreamDefaultControllerGetDesiredSize(this);
    }
    /**
     * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
     * the stream, but once those are read, the stream will become closed.
     */
    close() {
        if (!IsReadableStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException$1('close');
        }
        if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
            throw new TypeError('The stream is not in a state that permits close');
        }
        ReadableStreamDefaultControllerClose(this);
    }
    enqueue(chunk = undefined) {
        if (!IsReadableStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException$1('enqueue');
        }
        if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
            throw new TypeError('The stream is not in a state that permits enqueue');
        }
        return ReadableStreamDefaultControllerEnqueue(this, chunk);
    }
    /**
     * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
     */
    error(e = undefined) {
        if (!IsReadableStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException$1('error');
        }
        ReadableStreamDefaultControllerError(this, e);
    }
    /** @internal */
    [CancelSteps](reason) {
        ResetQueue(this);
        const result = this._cancelAlgorithm(reason);
        ReadableStreamDefaultControllerClearAlgorithms(this);
        return result;
    }
    /** @internal */
    [PullSteps](readRequest) {
        const stream = this._controlledReadableStream;
        if (this._queue.length > 0) {
            const chunk = DequeueValue(this);
            if (this._closeRequested && this._queue.length === 0) {
                ReadableStreamDefaultControllerClearAlgorithms(this);
                ReadableStreamClose(stream);
            }
            else {
                ReadableStreamDefaultControllerCallPullIfNeeded(this);
            }
            readRequest._chunkSteps(chunk);
        }
        else {
            ReadableStreamAddReadRequest(stream, readRequest);
            ReadableStreamDefaultControllerCallPullIfNeeded(this);
        }
    }
}
Object.defineProperties(ReadableStreamDefaultController.prototype, {
    close: { enumerable: true },
    enqueue: { enumerable: true },
    error: { enumerable: true },
    desiredSize: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(ReadableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
        value: 'ReadableStreamDefaultController',
        configurable: true
    });
}
// Abstract operations for the ReadableStreamDefaultController.
function IsReadableStreamDefaultController(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableStream')) {
        return false;
    }
    return true;
}
function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
    const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller);
    if (!shouldPull) {
        return;
    }
    if (controller._pulling) {
        controller._pullAgain = true;
        return;
    }
    controller._pulling = true;
    const pullPromise = controller._pullAlgorithm();
    uponPromise(pullPromise, () => {
        controller._pulling = false;
        if (controller._pullAgain) {
            controller._pullAgain = false;
            ReadableStreamDefaultControllerCallPullIfNeeded(controller);
        }
    }, e => {
        ReadableStreamDefaultControllerError(controller, e);
    });
}
function ReadableStreamDefaultControllerShouldCallPull(controller) {
    const stream = controller._controlledReadableStream;
    if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
        return false;
    }
    if (!controller._started) {
        return false;
    }
    if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
        return true;
    }
    const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller);
    if (desiredSize > 0) {
        return true;
    }
    return false;
}
function ReadableStreamDefaultControllerClearAlgorithms(controller) {
    controller._pullAlgorithm = undefined;
    controller._cancelAlgorithm = undefined;
    controller._strategySizeAlgorithm = undefined;
}
// A client of ReadableStreamDefaultController may use these functions directly to bypass state check.
function ReadableStreamDefaultControllerClose(controller) {
    if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
        return;
    }
    const stream = controller._controlledReadableStream;
    controller._closeRequested = true;
    if (controller._queue.length === 0) {
        ReadableStreamDefaultControllerClearAlgorithms(controller);
        ReadableStreamClose(stream);
    }
}
function ReadableStreamDefaultControllerEnqueue(controller, chunk) {
    if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
        return;
    }
    const stream = controller._controlledReadableStream;
    if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
        ReadableStreamFulfillReadRequest(stream, chunk, false);
    }
    else {
        let chunkSize;
        try {
            chunkSize = controller._strategySizeAlgorithm(chunk);
        }
        catch (chunkSizeE) {
            ReadableStreamDefaultControllerError(controller, chunkSizeE);
            throw chunkSizeE;
        }
        try {
            EnqueueValueWithSize(controller, chunk, chunkSize);
        }
        catch (enqueueE) {
            ReadableStreamDefaultControllerError(controller, enqueueE);
            throw enqueueE;
        }
    }
    ReadableStreamDefaultControllerCallPullIfNeeded(controller);
}
function ReadableStreamDefaultControllerError(controller, e) {
    const stream = controller._controlledReadableStream;
    if (stream._state !== 'readable') {
        return;
    }
    ResetQueue(controller);
    ReadableStreamDefaultControllerClearAlgorithms(controller);
    ReadableStreamError(stream, e);
}
function ReadableStreamDefaultControllerGetDesiredSize(controller) {
    const state = controller._controlledReadableStream._state;
    if (state === 'errored') {
        return null;
    }
    if (state === 'closed') {
        return 0;
    }
    return controller._strategyHWM - controller._queueTotalSize;
}
// This is used in the implementation of TransformStream.
function ReadableStreamDefaultControllerHasBackpressure(controller) {
    if (ReadableStreamDefaultControllerShouldCallPull(controller)) {
        return false;
    }
    return true;
}
function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) {
    const state = controller._controlledReadableStream._state;
    if (!controller._closeRequested && state === 'readable') {
        return true;
    }
    return false;
}
function SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm) {
    controller._controlledReadableStream = stream;
    controller._queue = undefined;
    controller._queueTotalSize = undefined;
    ResetQueue(controller);
    controller._started = false;
    controller._closeRequested = false;
    controller._pullAgain = false;
    controller._pulling = false;
    controller._strategySizeAlgorithm = sizeAlgorithm;
    controller._strategyHWM = highWaterMark;
    controller._pullAlgorithm = pullAlgorithm;
    controller._cancelAlgorithm = cancelAlgorithm;
    stream._readableStreamController = controller;
    const startResult = startAlgorithm();
    uponPromise(promiseResolvedWith(startResult), () => {
        controller._started = true;
        ReadableStreamDefaultControllerCallPullIfNeeded(controller);
    }, r => {
        ReadableStreamDefaultControllerError(controller, r);
    });
}
function SetUpReadableStreamDefaultControllerFromUnderlyingSource(stream, underlyingSource, highWaterMark, sizeAlgorithm) {
    const controller = Object.create(ReadableStreamDefaultController.prototype);
    let startAlgorithm = () => undefined;
    let pullAlgorithm = () => promiseResolvedWith(undefined);
    let cancelAlgorithm = () => promiseResolvedWith(undefined);
    if (underlyingSource.start !== undefined) {
        startAlgorithm = () => underlyingSource.start(controller);
    }
    if (underlyingSource.pull !== undefined) {
        pullAlgorithm = () => underlyingSource.pull(controller);
    }
    if (underlyingSource.cancel !== undefined) {
        cancelAlgorithm = reason => underlyingSource.cancel(reason);
    }
    SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
}
// Helper functions for the ReadableStreamDefaultController.
function defaultControllerBrandCheckException$1(name) {
    return new TypeError(`ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController`);
}

function ReadableStreamTee(stream, cloneForBranch2) {
    const reader = AcquireReadableStreamDefaultReader(stream);
    let reading = false;
    let canceled1 = false;
    let canceled2 = false;
    let reason1;
    let reason2;
    let branch1;
    let branch2;
    let resolveCancelPromise;
    const cancelPromise = newPromise(resolve => {
        resolveCancelPromise = resolve;
    });
    function pullAlgorithm() {
        if (reading) {
            return promiseResolvedWith(undefined);
        }
        reading = true;
        const readRequest = {
            _chunkSteps: value => {
                // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using
                // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
                // successful synchronously-available reads get ahead of asynchronously-available errors.
                queueMicrotask(() => {
                    reading = false;
                    const value1 = value;
                    const value2 = value;
                    // There is no way to access the cloning code right now in the reference implementation.
                    // If we add one then we'll need an implementation for serializable objects.
                    // if (!canceled2 && cloneForBranch2) {
                    //   value2 = StructuredDeserialize(StructuredSerialize(value2));
                    // }
                    if (!canceled1) {
                        ReadableStreamDefaultControllerEnqueue(branch1._readableStreamController, value1);
                    }
                    if (!canceled2) {
                        ReadableStreamDefaultControllerEnqueue(branch2._readableStreamController, value2);
                    }
                });
            },
            _closeSteps: () => {
                reading = false;
                if (!canceled1) {
                    ReadableStreamDefaultControllerClose(branch1._readableStreamController);
                }
                if (!canceled2) {
                    ReadableStreamDefaultControllerClose(branch2._readableStreamController);
                }
                if (!canceled1 || !canceled2) {
                    resolveCancelPromise(undefined);
                }
            },
            _errorSteps: () => {
                reading = false;
            }
        };
        ReadableStreamDefaultReaderRead(reader, readRequest);
        return promiseResolvedWith(undefined);
    }
    function cancel1Algorithm(reason) {
        canceled1 = true;
        reason1 = reason;
        if (canceled2) {
            const compositeReason = CreateArrayFromList([reason1, reason2]);
            const cancelResult = ReadableStreamCancel(stream, compositeReason);
            resolveCancelPromise(cancelResult);
        }
        return cancelPromise;
    }
    function cancel2Algorithm(reason) {
        canceled2 = true;
        reason2 = reason;
        if (canceled1) {
            const compositeReason = CreateArrayFromList([reason1, reason2]);
            const cancelResult = ReadableStreamCancel(stream, compositeReason);
            resolveCancelPromise(cancelResult);
        }
        return cancelPromise;
    }
    function startAlgorithm() {
        // do nothing
    }
    branch1 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel1Algorithm);
    branch2 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel2Algorithm);
    uponRejection(reader._closedPromise, (r) => {
        ReadableStreamDefaultControllerError(branch1._readableStreamController, r);
        ReadableStreamDefaultControllerError(branch2._readableStreamController, r);
        if (!canceled1 || !canceled2) {
            resolveCancelPromise(undefined);
        }
    });
    return [branch1, branch2];
}

function convertUnderlyingDefaultOrByteSource(source, context) {
    assertDictionary(source, context);
    const original = source;
    const autoAllocateChunkSize = original === null || original === void 0 ? void 0 : original.autoAllocateChunkSize;
    const cancel = original === null || original === void 0 ? void 0 : original.cancel;
    const pull = original === null || original === void 0 ? void 0 : original.pull;
    const start = original === null || original === void 0 ? void 0 : original.start;
    const type = original === null || original === void 0 ? void 0 : original.type;
    return {
        autoAllocateChunkSize: autoAllocateChunkSize === undefined ?
            undefined :
            convertUnsignedLongLongWithEnforceRange(autoAllocateChunkSize, `${context} has member 'autoAllocateChunkSize' that`),
        cancel: cancel === undefined ?
            undefined :
            convertUnderlyingSourceCancelCallback(cancel, original, `${context} has member 'cancel' that`),
        pull: pull === undefined ?
            undefined :
            convertUnderlyingSourcePullCallback(pull, original, `${context} has member 'pull' that`),
        start: start === undefined ?
            undefined :
            convertUnderlyingSourceStartCallback(start, original, `${context} has member 'start' that`),
        type: type === undefined ? undefined : convertReadableStreamType(type, `${context} has member 'type' that`)
    };
}
function convertUnderlyingSourceCancelCallback(fn, original, context) {
    assertFunction(fn, context);
    return (reason) => promiseCall(fn, original, [reason]);
}
function convertUnderlyingSourcePullCallback(fn, original, context) {
    assertFunction(fn, context);
    return (controller) => promiseCall(fn, original, [controller]);
}
function convertUnderlyingSourceStartCallback(fn, original, context) {
    assertFunction(fn, context);
    return (controller) => reflectCall(fn, original, [controller]);
}
function convertReadableStreamType(type, context) {
    type = `${type}`;
    if (type !== 'bytes') {
        throw new TypeError(`${context} '${type}' is not a valid enumeration value for ReadableStreamType`);
    }
    return type;
}

function convertReaderOptions(options, context) {
    assertDictionary(options, context);
    const mode = options === null || options === void 0 ? void 0 : options.mode;
    return {
        mode: mode === undefined ? undefined : convertReadableStreamReaderMode(mode, `${context} has member 'mode' that`)
    };
}
function convertReadableStreamReaderMode(mode, context) {
    mode = `${mode}`;
    if (mode !== 'byob') {
        throw new TypeError(`${context} '${mode}' is not a valid enumeration value for ReadableStreamReaderMode`);
    }
    return mode;
}

function convertIteratorOptions(options, context) {
    assertDictionary(options, context);
    const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
    return { preventCancel: Boolean(preventCancel) };
}

function convertPipeOptions(options, context) {
    assertDictionary(options, context);
    const preventAbort = options === null || options === void 0 ? void 0 : options.preventAbort;
    const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
    const preventClose = options === null || options === void 0 ? void 0 : options.preventClose;
    const signal = options === null || options === void 0 ? void 0 : options.signal;
    if (signal !== undefined) {
        assertAbortSignal(signal, `${context} has member 'signal' that`);
    }
    return {
        preventAbort: Boolean(preventAbort),
        preventCancel: Boolean(preventCancel),
        preventClose: Boolean(preventClose),
        signal
    };
}
function assertAbortSignal(signal, context) {
    if (!isAbortSignal(signal)) {
        throw new TypeError(`${context} is not an AbortSignal.`);
    }
}

function convertReadableWritablePair(pair, context) {
    assertDictionary(pair, context);
    const readable = pair === null || pair === void 0 ? void 0 : pair.readable;
    assertRequiredField(readable, 'readable', 'ReadableWritablePair');
    assertReadableStream(readable, `${context} has member 'readable' that`);
    const writable = pair === null || pair === void 0 ? void 0 : pair.writable;
    assertRequiredField(writable, 'writable', 'ReadableWritablePair');
    assertWritableStream(writable, `${context} has member 'writable' that`);
    return { readable, writable };
}

/**
 * A readable stream represents a source of data, from which you can read.
 *
 * @public
 */
class ReadableStream$1 {
    constructor(rawUnderlyingSource = {}, rawStrategy = {}) {
        if (rawUnderlyingSource === undefined) {
            rawUnderlyingSource = null;
        }
        else {
            assertObject(rawUnderlyingSource, 'First parameter');
        }
        const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
        const underlyingSource = convertUnderlyingDefaultOrByteSource(rawUnderlyingSource, 'First parameter');
        InitializeReadableStream(this);
        if (underlyingSource.type === 'bytes') {
            if (strategy.size !== undefined) {
                throw new RangeError('The strategy for a byte stream cannot have a size function');
            }
            const highWaterMark = ExtractHighWaterMark(strategy, 0);
            SetUpReadableByteStreamControllerFromUnderlyingSource(this, underlyingSource, highWaterMark);
        }
        else {
            const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
            const highWaterMark = ExtractHighWaterMark(strategy, 1);
            SetUpReadableStreamDefaultControllerFromUnderlyingSource(this, underlyingSource, highWaterMark, sizeAlgorithm);
        }
    }
    /**
     * Whether or not the readable stream is locked to a {@link ReadableStreamDefaultReader | reader}.
     */
    get locked() {
        if (!IsReadableStream(this)) {
            throw streamBrandCheckException$1('locked');
        }
        return IsReadableStreamLocked(this);
    }
    /**
     * Cancels the stream, signaling a loss of interest in the stream by a consumer.
     *
     * The supplied `reason` argument will be given to the underlying source's {@link UnderlyingSource.cancel | cancel()}
     * method, which might or might not use it.
     */
    cancel(reason = undefined) {
        if (!IsReadableStream(this)) {
            return promiseRejectedWith(streamBrandCheckException$1('cancel'));
        }
        if (IsReadableStreamLocked(this)) {
            return promiseRejectedWith(new TypeError('Cannot cancel a stream that already has a reader'));
        }
        return ReadableStreamCancel(this, reason);
    }
    getReader(rawOptions = undefined) {
        if (!IsReadableStream(this)) {
            throw streamBrandCheckException$1('getReader');
        }
        const options = convertReaderOptions(rawOptions, 'First parameter');
        if (options.mode === undefined) {
            return AcquireReadableStreamDefaultReader(this);
        }
        return AcquireReadableStreamBYOBReader(this);
    }
    pipeThrough(rawTransform, rawOptions = {}) {
        if (!IsReadableStream(this)) {
            throw streamBrandCheckException$1('pipeThrough');
        }
        assertRequiredArgument(rawTransform, 1, 'pipeThrough');
        const transform = convertReadableWritablePair(rawTransform, 'First parameter');
        const options = convertPipeOptions(rawOptions, 'Second parameter');
        if (IsReadableStreamLocked(this)) {
            throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream');
        }
        if (IsWritableStreamLocked(transform.writable)) {
            throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream');
        }
        const promise = ReadableStreamPipeTo(this, transform.writable, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
        setPromiseIsHandledToTrue(promise);
        return transform.readable;
    }
    pipeTo(destination, rawOptions = {}) {
        if (!IsReadableStream(this)) {
            return promiseRejectedWith(streamBrandCheckException$1('pipeTo'));
        }
        if (destination === undefined) {
            return promiseRejectedWith(`Parameter 1 is required in 'pipeTo'.`);
        }
        if (!IsWritableStream(destination)) {
            return promiseRejectedWith(new TypeError(`ReadableStream.prototype.pipeTo's first argument must be a WritableStream`));
        }
        let options;
        try {
            options = convertPipeOptions(rawOptions, 'Second parameter');
        }
        catch (e) {
            return promiseRejectedWith(e);
        }
        if (IsReadableStreamLocked(this)) {
            return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream'));
        }
        if (IsWritableStreamLocked(destination)) {
            return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream'));
        }
        return ReadableStreamPipeTo(this, destination, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
    }
    /**
     * Tees this readable stream, returning a two-element array containing the two resulting branches as
     * new {@link ReadableStream} instances.
     *
     * Teeing a stream will lock it, preventing any other consumer from acquiring a reader.
     * To cancel the stream, cancel both of the resulting branches; a composite cancellation reason will then be
     * propagated to the stream's underlying source.
     *
     * Note that the chunks seen in each branch will be the same object. If the chunks are not immutable,
     * this could allow interference between the two branches.
     */
    tee() {
        if (!IsReadableStream(this)) {
            throw streamBrandCheckException$1('tee');
        }
        const branches = ReadableStreamTee(this);
        return CreateArrayFromList(branches);
    }
    values(rawOptions = undefined) {
        if (!IsReadableStream(this)) {
            throw streamBrandCheckException$1('values');
        }
        const options = convertIteratorOptions(rawOptions, 'First parameter');
        return AcquireReadableStreamAsyncIterator(this, options.preventCancel);
    }
}
Object.defineProperties(ReadableStream$1.prototype, {
    cancel: { enumerable: true },
    getReader: { enumerable: true },
    pipeThrough: { enumerable: true },
    pipeTo: { enumerable: true },
    tee: { enumerable: true },
    values: { enumerable: true },
    locked: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(ReadableStream$1.prototype, SymbolPolyfill.toStringTag, {
        value: 'ReadableStream',
        configurable: true
    });
}
if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
    Object.defineProperty(ReadableStream$1.prototype, SymbolPolyfill.asyncIterator, {
        value: ReadableStream$1.prototype.values,
        writable: true,
        configurable: true
    });
}
// Abstract operations for the ReadableStream.
// Throws if and only if startAlgorithm throws.
function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
    const stream = Object.create(ReadableStream$1.prototype);
    InitializeReadableStream(stream);
    const controller = Object.create(ReadableStreamDefaultController.prototype);
    SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
    return stream;
}
function InitializeReadableStream(stream) {
    stream._state = 'readable';
    stream._reader = undefined;
    stream._storedError = undefined;
    stream._disturbed = false;
}
function IsReadableStream(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_readableStreamController')) {
        return false;
    }
    return true;
}
function IsReadableStreamLocked(stream) {
    if (stream._reader === undefined) {
        return false;
    }
    return true;
}
// ReadableStream API exposed for controllers.
function ReadableStreamCancel(stream, reason) {
    stream._disturbed = true;
    if (stream._state === 'closed') {
        return promiseResolvedWith(undefined);
    }
    if (stream._state === 'errored') {
        return promiseRejectedWith(stream._storedError);
    }
    ReadableStreamClose(stream);
    const sourceCancelPromise = stream._readableStreamController[CancelSteps](reason);
    return transformPromiseWith(sourceCancelPromise, noop);
}
function ReadableStreamClose(stream) {
    stream._state = 'closed';
    const reader = stream._reader;
    if (reader === undefined) {
        return;
    }
    defaultReaderClosedPromiseResolve(reader);
    if (IsReadableStreamDefaultReader(reader)) {
        reader._readRequests.forEach(readRequest => {
            readRequest._closeSteps();
        });
        reader._readRequests = new SimpleQueue();
    }
}
function ReadableStreamError(stream, e) {
    stream._state = 'errored';
    stream._storedError = e;
    const reader = stream._reader;
    if (reader === undefined) {
        return;
    }
    defaultReaderClosedPromiseReject(reader, e);
    if (IsReadableStreamDefaultReader(reader)) {
        reader._readRequests.forEach(readRequest => {
            readRequest._errorSteps(e);
        });
        reader._readRequests = new SimpleQueue();
    }
    else {
        reader._readIntoRequests.forEach(readIntoRequest => {
            readIntoRequest._errorSteps(e);
        });
        reader._readIntoRequests = new SimpleQueue();
    }
}
// Helper functions for the ReadableStream.
function streamBrandCheckException$1(name) {
    return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`);
}

function convertQueuingStrategyInit(init, context) {
    assertDictionary(init, context);
    const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
    assertRequiredField(highWaterMark, 'highWaterMark', 'QueuingStrategyInit');
    return {
        highWaterMark: convertUnrestrictedDouble(highWaterMark)
    };
}

const byteLengthSizeFunction = function size(chunk) {
    return chunk.byteLength;
};
/**
 * A queuing strategy that counts the number of bytes in each chunk.
 *
 * @public
 */
class ByteLengthQueuingStrategy {
    constructor(options) {
        assertRequiredArgument(options, 1, 'ByteLengthQueuingStrategy');
        options = convertQueuingStrategyInit(options, 'First parameter');
        this._byteLengthQueuingStrategyHighWaterMark = options.highWaterMark;
    }
    /**
     * Returns the high water mark provided to the constructor.
     */
    get highWaterMark() {
        if (!IsByteLengthQueuingStrategy(this)) {
            throw byteLengthBrandCheckException('highWaterMark');
        }
        return this._byteLengthQueuingStrategyHighWaterMark;
    }
    /**
     * Measures the size of `chunk` by returning the value of its `byteLength` property.
     */
    get size() {
        if (!IsByteLengthQueuingStrategy(this)) {
            throw byteLengthBrandCheckException('size');
        }
        return byteLengthSizeFunction;
    }
}
Object.defineProperties(ByteLengthQueuingStrategy.prototype, {
    highWaterMark: { enumerable: true },
    size: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(ByteLengthQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
        value: 'ByteLengthQueuingStrategy',
        configurable: true
    });
}
// Helper functions for the ByteLengthQueuingStrategy.
function byteLengthBrandCheckException(name) {
    return new TypeError(`ByteLengthQueuingStrategy.prototype.${name} can only be used on a ByteLengthQueuingStrategy`);
}
function IsByteLengthQueuingStrategy(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_byteLengthQueuingStrategyHighWaterMark')) {
        return false;
    }
    return true;
}

const countSizeFunction = function size() {
    return 1;
};
/**
 * A queuing strategy that counts the number of chunks.
 *
 * @public
 */
class CountQueuingStrategy {
    constructor(options) {
        assertRequiredArgument(options, 1, 'CountQueuingStrategy');
        options = convertQueuingStrategyInit(options, 'First parameter');
        this._countQueuingStrategyHighWaterMark = options.highWaterMark;
    }
    /**
     * Returns the high water mark provided to the constructor.
     */
    get highWaterMark() {
        if (!IsCountQueuingStrategy(this)) {
            throw countBrandCheckException('highWaterMark');
        }
        return this._countQueuingStrategyHighWaterMark;
    }
    /**
     * Measures the size of `chunk` by always returning 1.
     * This ensures that the total queue size is a count of the number of chunks in the queue.
     */
    get size() {
        if (!IsCountQueuingStrategy(this)) {
            throw countBrandCheckException('size');
        }
        return countSizeFunction;
    }
}
Object.defineProperties(CountQueuingStrategy.prototype, {
    highWaterMark: { enumerable: true },
    size: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(CountQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
        value: 'CountQueuingStrategy',
        configurable: true
    });
}
// Helper functions for the CountQueuingStrategy.
function countBrandCheckException(name) {
    return new TypeError(`CountQueuingStrategy.prototype.${name} can only be used on a CountQueuingStrategy`);
}
function IsCountQueuingStrategy(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_countQueuingStrategyHighWaterMark')) {
        return false;
    }
    return true;
}

function convertTransformer(original, context) {
    assertDictionary(original, context);
    const flush = original === null || original === void 0 ? void 0 : original.flush;
    const readableType = original === null || original === void 0 ? void 0 : original.readableType;
    const start = original === null || original === void 0 ? void 0 : original.start;
    const transform = original === null || original === void 0 ? void 0 : original.transform;
    const writableType = original === null || original === void 0 ? void 0 : original.writableType;
    return {
        flush: flush === undefined ?
            undefined :
            convertTransformerFlushCallback(flush, original, `${context} has member 'flush' that`),
        readableType,
        start: start === undefined ?
            undefined :
            convertTransformerStartCallback(start, original, `${context} has member 'start' that`),
        transform: transform === undefined ?
            undefined :
            convertTransformerTransformCallback(transform, original, `${context} has member 'transform' that`),
        writableType
    };
}
function convertTransformerFlushCallback(fn, original, context) {
    assertFunction(fn, context);
    return (controller) => promiseCall(fn, original, [controller]);
}
function convertTransformerStartCallback(fn, original, context) {
    assertFunction(fn, context);
    return (controller) => reflectCall(fn, original, [controller]);
}
function convertTransformerTransformCallback(fn, original, context) {
    assertFunction(fn, context);
    return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
}

// Class TransformStream
/**
 * A transform stream consists of a pair of streams: a {@link WritableStream | writable stream},
 * known as its writable side, and a {@link ReadableStream | readable stream}, known as its readable side.
 * In a manner specific to the transform stream in question, writes to the writable side result in new data being
 * made available for reading from the readable side.
 *
 * @public
 */
class TransformStream$1 {
    constructor(rawTransformer = {}, rawWritableStrategy = {}, rawReadableStrategy = {}) {
        if (rawTransformer === undefined) {
            rawTransformer = null;
        }
        const writableStrategy = convertQueuingStrategy(rawWritableStrategy, 'Second parameter');
        const readableStrategy = convertQueuingStrategy(rawReadableStrategy, 'Third parameter');
        const transformer = convertTransformer(rawTransformer, 'First parameter');
        if (transformer.readableType !== undefined) {
            throw new RangeError('Invalid readableType specified');
        }
        if (transformer.writableType !== undefined) {
            throw new RangeError('Invalid writableType specified');
        }
        const readableHighWaterMark = ExtractHighWaterMark(readableStrategy, 0);
        const readableSizeAlgorithm = ExtractSizeAlgorithm(readableStrategy);
        const writableHighWaterMark = ExtractHighWaterMark(writableStrategy, 1);
        const writableSizeAlgorithm = ExtractSizeAlgorithm(writableStrategy);
        let startPromise_resolve;
        const startPromise = newPromise(resolve => {
            startPromise_resolve = resolve;
        });
        InitializeTransformStream(this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
        SetUpTransformStreamDefaultControllerFromTransformer(this, transformer);
        if (transformer.start !== undefined) {
            startPromise_resolve(transformer.start(this._transformStreamController));
        }
        else {
            startPromise_resolve(undefined);
        }
    }
    /**
     * The readable side of the transform stream.
     */
    get readable() {
        if (!IsTransformStream(this)) {
            throw streamBrandCheckException('readable');
        }
        return this._readable;
    }
    /**
     * The writable side of the transform stream.
     */
    get writable() {
        if (!IsTransformStream(this)) {
            throw streamBrandCheckException('writable');
        }
        return this._writable;
    }
}
Object.defineProperties(TransformStream$1.prototype, {
    readable: { enumerable: true },
    writable: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(TransformStream$1.prototype, SymbolPolyfill.toStringTag, {
        value: 'TransformStream',
        configurable: true
    });
}
function InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) {
    function startAlgorithm() {
        return startPromise;
    }
    function writeAlgorithm(chunk) {
        return TransformStreamDefaultSinkWriteAlgorithm(stream, chunk);
    }
    function abortAlgorithm(reason) {
        return TransformStreamDefaultSinkAbortAlgorithm(stream, reason);
    }
    function closeAlgorithm() {
        return TransformStreamDefaultSinkCloseAlgorithm(stream);
    }
    stream._writable = CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm);
    function pullAlgorithm() {
        return TransformStreamDefaultSourcePullAlgorithm(stream);
    }
    function cancelAlgorithm(reason) {
        TransformStreamErrorWritableAndUnblockWrite(stream, reason);
        return promiseResolvedWith(undefined);
    }
    stream._readable = CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
    // The [[backpressure]] slot is set to undefined so that it can be initialised by TransformStreamSetBackpressure.
    stream._backpressure = undefined;
    stream._backpressureChangePromise = undefined;
    stream._backpressureChangePromise_resolve = undefined;
    TransformStreamSetBackpressure(stream, true);
    stream._transformStreamController = undefined;
}
function IsTransformStream(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) {
        return false;
    }
    return true;
}
// This is a no-op if both sides are already errored.
function TransformStreamError(stream, e) {
    ReadableStreamDefaultControllerError(stream._readable._readableStreamController, e);
    TransformStreamErrorWritableAndUnblockWrite(stream, e);
}
function TransformStreamErrorWritableAndUnblockWrite(stream, e) {
    TransformStreamDefaultControllerClearAlgorithms(stream._transformStreamController);
    WritableStreamDefaultControllerErrorIfNeeded(stream._writable._writableStreamController, e);
    if (stream._backpressure) {
        // Pretend that pull() was called to permit any pending write() calls to complete. TransformStreamSetBackpressure()
        // cannot be called from enqueue() or pull() once the ReadableStream is errored, so this will will be the final time
        // _backpressure is set.
        TransformStreamSetBackpressure(stream, false);
    }
}
function TransformStreamSetBackpressure(stream, backpressure) {
    // Passes also when called during construction.
    if (stream._backpressureChangePromise !== undefined) {
        stream._backpressureChangePromise_resolve();
    }
    stream._backpressureChangePromise = newPromise(resolve => {
        stream._backpressureChangePromise_resolve = resolve;
    });
    stream._backpressure = backpressure;
}
// Class TransformStreamDefaultController
/**
 * Allows control of the {@link ReadableStream} and {@link WritableStream} of the associated {@link TransformStream}.
 *
 * @public
 */
class TransformStreamDefaultController {
    constructor() {
        throw new TypeError('Illegal constructor');
    }
    /**
     * Returns the desired size to fill the readable side’s internal queue. It can be negative, if the queue is over-full.
     */
    get desiredSize() {
        if (!IsTransformStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException('desiredSize');
        }
        const readableController = this._controlledTransformStream._readable._readableStreamController;
        return ReadableStreamDefaultControllerGetDesiredSize(readableController);
    }
    enqueue(chunk = undefined) {
        if (!IsTransformStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException('enqueue');
        }
        TransformStreamDefaultControllerEnqueue(this, chunk);
    }
    /**
     * Errors both the readable side and the writable side of the controlled transform stream, making all future
     * interactions with it fail with the given error `e`. Any chunks queued for transformation will be discarded.
     */
    error(reason = undefined) {
        if (!IsTransformStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException('error');
        }
        TransformStreamDefaultControllerError(this, reason);
    }
    /**
     * Closes the readable side and errors the writable side of the controlled transform stream. This is useful when the
     * transformer only needs to consume a portion of the chunks written to the writable side.
     */
    terminate() {
        if (!IsTransformStreamDefaultController(this)) {
            throw defaultControllerBrandCheckException('terminate');
        }
        TransformStreamDefaultControllerTerminate(this);
    }
}
Object.defineProperties(TransformStreamDefaultController.prototype, {
    enqueue: { enumerable: true },
    error: { enumerable: true },
    terminate: { enumerable: true },
    desiredSize: { enumerable: true }
});
if (typeof SymbolPolyfill.toStringTag === 'symbol') {
    Object.defineProperty(TransformStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
        value: 'TransformStreamDefaultController',
        configurable: true
    });
}
// Transform Stream Default Controller Abstract Operations
function IsTransformStreamDefaultController(x) {
    if (!typeIsObject(x)) {
        return false;
    }
    if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) {
        return false;
    }
    return true;
}
function SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm) {
    controller._controlledTransformStream = stream;
    stream._transformStreamController = controller;
    controller._transformAlgorithm = transformAlgorithm;
    controller._flushAlgorithm = flushAlgorithm;
}
function SetUpTransformStreamDefaultControllerFromTransformer(stream, transformer) {
    const controller = Object.create(TransformStreamDefaultController.prototype);
    let transformAlgorithm = (chunk) => {
        try {
            TransformStreamDefaultControllerEnqueue(controller, chunk);
            return promiseResolvedWith(undefined);
        }
        catch (transformResultE) {
            return promiseRejectedWith(transformResultE);
        }
    };
    let flushAlgorithm = () => promiseResolvedWith(undefined);
    if (transformer.transform !== undefined) {
        transformAlgorithm = chunk => transformer.transform(chunk, controller);
    }
    if (transformer.flush !== undefined) {
        flushAlgorithm = () => transformer.flush(controller);
    }
    SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm);
}
function TransformStreamDefaultControllerClearAlgorithms(controller) {
    controller._transformAlgorithm = undefined;
    controller._flushAlgorithm = undefined;
}
function TransformStreamDefaultControllerEnqueue(controller, chunk) {
    const stream = controller._controlledTransformStream;
    const readableController = stream._readable._readableStreamController;
    if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController)) {
        throw new TypeError('Readable side is not in a state that permits enqueue');
    }
    // We throttle transform invocations based on the backpressure of the ReadableStream, but we still
    // accept TransformStreamDefaultControllerEnqueue() calls.
    try {
        ReadableStreamDefaultControllerEnqueue(readableController, chunk);
    }
    catch (e) {
        // This happens when readableStrategy.size() throws.
        TransformStreamErrorWritableAndUnblockWrite(stream, e);
        throw stream._readable._storedError;
    }
    const backpressure = ReadableStreamDefaultControllerHasBackpressure(readableController);
    if (backpressure !== stream._backpressure) {
        TransformStreamSetBackpressure(stream, true);
    }
}
function TransformStreamDefaultControllerError(controller, e) {
    TransformStreamError(controller._controlledTransformStream, e);
}
function TransformStreamDefaultControllerPerformTransform(controller, chunk) {
    const transformPromise = controller._transformAlgorithm(chunk);
    return transformPromiseWith(transformPromise, undefined, r => {
        TransformStreamError(controller._controlledTransformStream, r);
        throw r;
    });
}
function TransformStreamDefaultControllerTerminate(controller) {
    const stream = controller._controlledTransformStream;
    const readableController = stream._readable._readableStreamController;
    ReadableStreamDefaultControllerClose(readableController);
    const error = new TypeError('TransformStream terminated');
    TransformStreamErrorWritableAndUnblockWrite(stream, error);
}
// TransformStreamDefaultSink Algorithms
function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
    const controller = stream._transformStreamController;
    if (stream._backpressure) {
        const backpressureChangePromise = stream._backpressureChangePromise;
        return transformPromiseWith(backpressureChangePromise, () => {
            const writable = stream._writable;
            const state = writable._state;
            if (state === 'erroring') {
                throw writable._storedError;
            }
            return TransformStreamDefaultControllerPerformTransform(controller, chunk);
        });
    }
    return TransformStreamDefaultControllerPerformTransform(controller, chunk);
}
function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) {
    // abort() is not called synchronously, so it is possible for abort() to be called when the stream is already
    // errored.
    TransformStreamError(stream, reason);
    return promiseResolvedWith(undefined);
}
function TransformStreamDefaultSinkCloseAlgorithm(stream) {
    // stream._readable cannot change after construction, so caching it across a call to user code is safe.
    const readable = stream._readable;
    const controller = stream._transformStreamController;
    const flushPromise = controller._flushAlgorithm();
    TransformStreamDefaultControllerClearAlgorithms(controller);
    // Return a promise that is fulfilled with undefined on success.
    return transformPromiseWith(flushPromise, () => {
        if (readable._state === 'errored') {
            throw readable._storedError;
        }
        ReadableStreamDefaultControllerClose(readable._readableStreamController);
    }, r => {
        TransformStreamError(stream, r);
        throw readable._storedError;
    });
}
// TransformStreamDefaultSource Algorithms
function TransformStreamDefaultSourcePullAlgorithm(stream) {
    // Invariant. Enforced by the promises returned by start() and pull().
    TransformStreamSetBackpressure(stream, false);
    // Prevent the next pull() call until there is backpressure.
    return stream._backpressureChangePromise;
}
// Helper functions for the TransformStreamDefaultController.
function defaultControllerBrandCheckException(name) {
    return new TypeError(`TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController`);
}
// Helper functions for the TransformStream.
function streamBrandCheckException(name) {
    return new TypeError(`TransformStream.prototype.${name} can only be used on a TransformStream`);
}

var ponyfill_es6 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  ByteLengthQueuingStrategy: ByteLengthQueuingStrategy,
  CountQueuingStrategy: CountQueuingStrategy,
  ReadableByteStreamController: ReadableByteStreamController,
  ReadableStream: ReadableStream$1,
  ReadableStreamBYOBReader: ReadableStreamBYOBReader,
  ReadableStreamBYOBRequest: ReadableStreamBYOBRequest,
  ReadableStreamDefaultController: ReadableStreamDefaultController,
  ReadableStreamDefaultReader: ReadableStreamDefaultReader,
  TransformStream: TransformStream$1,
  TransformStreamDefaultController: TransformStreamDefaultController,
  WritableStream: WritableStream$1,
  WritableStreamDefaultController: WritableStreamDefaultController,
  WritableStreamDefaultWriter: WritableStreamDefaultWriter
});

/*! *****************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */

var extendStatics = function(d, b) {
    extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
    return extendStatics(d, b);
};

function __extends(d, b) {
    if (typeof b !== "function" && b !== null)
        throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
    extendStatics(d, b);
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

function assert$1(test) {
    if (!test) {
        throw new TypeError('Assertion failed');
    }
}

function noop$1() {
    return;
}
function typeIsObject$1(x) {
    return (typeof x === 'object' && x !== null) || typeof x === 'function';
}

function isStreamConstructor(ctor) {
    if (typeof ctor !== 'function') {
        return false;
    }
    var startCalled = false;
    try {
        new ctor({
            start: function () {
                startCalled = true;
            }
        });
    }
    catch (e) {
        // ignore
    }
    return startCalled;
}
function isReadableStream(readable) {
    if (!typeIsObject$1(readable)) {
        return false;
    }
    if (typeof readable.getReader !== 'function') {
        return false;
    }
    return true;
}
function isReadableStreamConstructor(ctor) {
    if (!isStreamConstructor(ctor)) {
        return false;
    }
    if (!isReadableStream(new ctor())) {
        return false;
    }
    return true;
}
function isWritableStream(writable) {
    if (!typeIsObject$1(writable)) {
        return false;
    }
    if (typeof writable.getWriter !== 'function') {
        return false;
    }
    return true;
}
function isWritableStreamConstructor(ctor) {
    if (!isStreamConstructor(ctor)) {
        return false;
    }
    if (!isWritableStream(new ctor())) {
        return false;
    }
    return true;
}
function isTransformStream(transform) {
    if (!typeIsObject$1(transform)) {
        return false;
    }
    if (!isReadableStream(transform.readable)) {
        return false;
    }
    if (!isWritableStream(transform.writable)) {
        return false;
    }
    return true;
}
function isTransformStreamConstructor(ctor) {
    if (!isStreamConstructor(ctor)) {
        return false;
    }
    if (!isTransformStream(new ctor())) {
        return false;
    }
    return true;
}
function supportsByobReader(readable) {
    try {
        var reader = readable.getReader({ mode: 'byob' });
        reader.releaseLock();
        return true;
    }
    catch (_a) {
        return false;
    }
}
function supportsByteSource(ctor) {
    try {
        new ctor({ type: 'bytes' });
        return true;
    }
    catch (_a) {
        return false;
    }
}

function createReadableStreamWrapper(ctor) {
    assert$1(isReadableStreamConstructor(ctor));
    var byteSourceSupported = supportsByteSource(ctor);
    return function (readable, _a) {
        var _b = _a === void 0 ? {} : _a, type = _b.type;
        type = parseReadableType(type);
        if (type === 'bytes' && !byteSourceSupported) {
            type = undefined;
        }
        if (readable.constructor === ctor) {
            if (type !== 'bytes' || supportsByobReader(readable)) {
                return readable;
            }
        }
        if (type === 'bytes') {
            var source = createWrappingReadableSource(readable, { type: type });
            return new ctor(source);
        }
        else {
            var source = createWrappingReadableSource(readable);
            return new ctor(source);
        }
    };
}
function createWrappingReadableSource(readable, _a) {
    var _b = _a === void 0 ? {} : _a, type = _b.type;
    assert$1(isReadableStream(readable));
    assert$1(readable.locked === false);
    type = parseReadableType(type);
    var source;
    if (type === 'bytes') {
        source = new WrappingReadableByteStreamSource(readable);
    }
    else {
        source = new WrappingReadableStreamDefaultSource(readable);
    }
    return source;
}
function parseReadableType(type) {
    var typeString = String(type);
    if (typeString === 'bytes') {
        return typeString;
    }
    else if (type === undefined) {
        return type;
    }
    else {
        throw new RangeError('Invalid type is specified');
    }
}
var AbstractWrappingReadableStreamSource = /** @class */ (function () {
    function AbstractWrappingReadableStreamSource(underlyingStream) {
        this._underlyingReader = undefined;
        this._readerMode = undefined;
        this._readableStreamController = undefined;
        this._pendingRead = undefined;
        this._underlyingStream = underlyingStream;
        // always keep a reader attached to detect close/error
        this._attachDefaultReader();
    }
    AbstractWrappingReadableStreamSource.prototype.start = function (controller) {
        this._readableStreamController = controller;
    };
    AbstractWrappingReadableStreamSource.prototype.cancel = function (reason) {
        assert$1(this._underlyingReader !== undefined);
        return this._underlyingReader.cancel(reason);
    };
    AbstractWrappingReadableStreamSource.prototype._attachDefaultReader = function () {
        if (this._readerMode === "default" /* DEFAULT */) {
            return;
        }
        this._detachReader();
        var reader = this._underlyingStream.getReader();
        this._readerMode = "default" /* DEFAULT */;
        this._attachReader(reader);
    };
    AbstractWrappingReadableStreamSource.prototype._attachReader = function (reader) {
        var _this = this;
        assert$1(this._underlyingReader === undefined);
        this._underlyingReader = reader;
        var closed = this._underlyingReader.closed;
        if (!closed) {
            return;
        }
        closed
            .then(function () { return _this._finishPendingRead(); })
            .then(function () {
            if (reader === _this._underlyingReader) {
                _this._readableStreamController.close();
            }
        }, function (reason) {
            if (reader === _this._underlyingReader) {
                _this._readableStreamController.error(reason);
            }
        })
            .catch(noop$1);
    };
    AbstractWrappingReadableStreamSource.prototype._detachReader = function () {
        if (this._underlyingReader === undefined) {
            return;
        }
        this._underlyingReader.releaseLock();
        this._underlyingReader = undefined;
        this._readerMode = undefined;
    };
    AbstractWrappingReadableStreamSource.prototype._pullWithDefaultReader = function () {
        var _this = this;
        this._attachDefaultReader();
        // TODO Backpressure?
        var read = this._underlyingReader.read()
            .then(function (result) {
            var controller = _this._readableStreamController;
            if (result.done) {
                _this._tryClose();
            }
            else {
                controller.enqueue(result.value);
            }
        });
        this._setPendingRead(read);
        return read;
    };
    AbstractWrappingReadableStreamSource.prototype._tryClose = function () {
        try {
            this._readableStreamController.close();
        }
        catch (_a) {
            // already errored or closed
        }
    };
    AbstractWrappingReadableStreamSource.prototype._setPendingRead = function (readPromise) {
        var _this = this;
        var pendingRead;
        var finishRead = function () {
            if (_this._pendingRead === pendingRead) {
                _this._pendingRead = undefined;
            }
        };
        this._pendingRead = pendingRead = readPromise.then(finishRead, finishRead);
    };
    AbstractWrappingReadableStreamSource.prototype._finishPendingRead = function () {
        var _this = this;
        if (!this._pendingRead) {
            return undefined;
        }
        var afterRead = function () { return _this._finishPendingRead(); };
        return this._pendingRead.then(afterRead, afterRead);
    };
    return AbstractWrappingReadableStreamSource;
}());
var WrappingReadableStreamDefaultSource = /** @class */ (function (_super) {
    __extends(WrappingReadableStreamDefaultSource, _super);
    function WrappingReadableStreamDefaultSource() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    WrappingReadableStreamDefaultSource.prototype.pull = function () {
        return this._pullWithDefaultReader();
    };
    return WrappingReadableStreamDefaultSource;
}(AbstractWrappingReadableStreamSource));
function toUint8Array(view) {
    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
}
function copyArrayBufferView(from, to) {
    var fromArray = toUint8Array(from);
    var toArray = toUint8Array(to);
    toArray.set(fromArray, 0);
}
var WrappingReadableByteStreamSource = /** @class */ (function (_super) {
    __extends(WrappingReadableByteStreamSource, _super);
    function WrappingReadableByteStreamSource(underlyingStream) {
        var _this = this;
        var supportsByob = supportsByobReader(underlyingStream);
        _this = _super.call(this, underlyingStream) || this;
        _this._supportsByob = supportsByob;
        return _this;
    }
    Object.defineProperty(WrappingReadableByteStreamSource.prototype, "type", {
        get: function () {
            return 'bytes';
        },
        enumerable: false,
        configurable: true
    });
    WrappingReadableByteStreamSource.prototype._attachByobReader = function () {
        if (this._readerMode === "byob" /* BYOB */) {
            return;
        }
        assert$1(this._supportsByob);
        this._detachReader();
        var reader = this._underlyingStream.getReader({ mode: 'byob' });
        this._readerMode = "byob" /* BYOB */;
        this._attachReader(reader);
    };
    WrappingReadableByteStreamSource.prototype.pull = function () {
        if (this._supportsByob) {
            var byobRequest = this._readableStreamController.byobRequest;
            if (byobRequest) {
                return this._pullWithByobRequest(byobRequest);
            }
        }
        return this._pullWithDefaultReader();
    };
    WrappingReadableByteStreamSource.prototype._pullWithByobRequest = function (byobRequest) {
        var _this = this;
        this._attachByobReader();
        // reader.read(view) detaches the input view, therefore we cannot pass byobRequest.view directly
        // create a separate buffer to read into, then copy that to byobRequest.view
        var buffer = new Uint8Array(byobRequest.view.byteLength);
        // TODO Backpressure?
        var read = this._underlyingReader.read(buffer)
            .then(function (result) {
            _this._readableStreamController;
            if (result.done) {
                _this._tryClose();
                byobRequest.respond(0);
            }
            else {
                copyArrayBufferView(result.value, byobRequest.view);
                byobRequest.respond(result.value.byteLength);
            }
        });
        this._setPendingRead(read);
        return read;
    };
    return WrappingReadableByteStreamSource;
}(AbstractWrappingReadableStreamSource));

function createWritableStreamWrapper(ctor) {
    assert$1(isWritableStreamConstructor(ctor));
    return function (writable) {
        if (writable.constructor === ctor) {
            return writable;
        }
        var sink = createWrappingWritableSink(writable);
        return new ctor(sink);
    };
}
function createWrappingWritableSink(writable) {
    assert$1(isWritableStream(writable));
    assert$1(writable.locked === false);
    var writer = writable.getWriter();
    return new WrappingWritableStreamSink(writer);
}
var WrappingWritableStreamSink = /** @class */ (function () {
    function WrappingWritableStreamSink(underlyingWriter) {
        var _this = this;
        this._writableStreamController = undefined;
        this._pendingWrite = undefined;
        this._state = "writable" /* WRITABLE */;
        this._storedError = undefined;
        this._underlyingWriter = underlyingWriter;
        this._errorPromise = new Promise(function (resolve, reject) {
            _this._errorPromiseReject = reject;
        });
        this._errorPromise.catch(noop$1);
    }
    WrappingWritableStreamSink.prototype.start = function (controller) {
        var _this = this;
        this._writableStreamController = controller;
        this._underlyingWriter.closed
            .then(function () {
            _this._state = "closed" /* CLOSED */;
        })
            .catch(function (reason) { return _this._finishErroring(reason); });
    };
    WrappingWritableStreamSink.prototype.write = function (chunk) {
        var _this = this;
        var writer = this._underlyingWriter;
        // Detect past errors
        if (writer.desiredSize === null) {
            return writer.ready;
        }
        var writeRequest = writer.write(chunk);
        // Detect future errors
        writeRequest.catch(function (reason) { return _this._finishErroring(reason); });
        writer.ready.catch(function (reason) { return _this._startErroring(reason); });
        // Reject write when errored
        var write = Promise.race([writeRequest, this._errorPromise]);
        this._setPendingWrite(write);
        return write;
    };
    WrappingWritableStreamSink.prototype.close = function () {
        var _this = this;
        if (this._pendingWrite === undefined) {
            return this._underlyingWriter.close();
        }
        return this._finishPendingWrite().then(function () { return _this.close(); });
    };
    WrappingWritableStreamSink.prototype.abort = function (reason) {
        if (this._state === "errored" /* ERRORED */) {
            return undefined;
        }
        var writer = this._underlyingWriter;
        return writer.abort(reason);
    };
    WrappingWritableStreamSink.prototype._setPendingWrite = function (writePromise) {
        var _this = this;
        var pendingWrite;
        var finishWrite = function () {
            if (_this._pendingWrite === pendingWrite) {
                _this._pendingWrite = undefined;
            }
        };
        this._pendingWrite = pendingWrite = writePromise.then(finishWrite, finishWrite);
    };
    WrappingWritableStreamSink.prototype._finishPendingWrite = function () {
        var _this = this;
        if (this._pendingWrite === undefined) {
            return Promise.resolve();
        }
        var afterWrite = function () { return _this._finishPendingWrite(); };
        return this._pendingWrite.then(afterWrite, afterWrite);
    };
    WrappingWritableStreamSink.prototype._startErroring = function (reason) {
        var _this = this;
        if (this._state === "writable" /* WRITABLE */) {
            this._state = "erroring" /* ERRORING */;
            this._storedError = reason;
            var afterWrite = function () { return _this._finishErroring(reason); };
            if (this._pendingWrite === undefined) {
                afterWrite();
            }
            else {
                this._finishPendingWrite().then(afterWrite, afterWrite);
            }
            this._writableStreamController.error(reason);
        }
    };
    WrappingWritableStreamSink.prototype._finishErroring = function (reason) {
        if (this._state === "writable" /* WRITABLE */) {
            this._startErroring(reason);
        }
        if (this._state === "erroring" /* ERRORING */) {
            this._state = "errored" /* ERRORED */;
            this._errorPromiseReject(this._storedError);
        }
    };
    return WrappingWritableStreamSink;
}());

function createTransformStreamWrapper(ctor) {
    assert$1(isTransformStreamConstructor(ctor));
    return function (transform) {
        if (transform.constructor === ctor) {
            return transform;
        }
        var transformer = createWrappingTransformer(transform);
        return new ctor(transformer);
    };
}
function createWrappingTransformer(transform) {
    assert$1(isTransformStream(transform));
    var readable = transform.readable, writable = transform.writable;
    assert$1(readable.locked === false);
    assert$1(writable.locked === false);
    var reader = readable.getReader();
    var writer;
    try {
        writer = writable.getWriter();
    }
    catch (e) {
        reader.releaseLock(); // do not leak reader
        throw e;
    }
    return new WrappingTransformStreamTransformer(reader, writer);
}
var WrappingTransformStreamTransformer = /** @class */ (function () {
    function WrappingTransformStreamTransformer(reader, writer) {
        var _this = this;
        this._transformStreamController = undefined;
        this._onRead = function (result) {
            if (result.done) {
                return;
            }
            _this._transformStreamController.enqueue(result.value);
            return _this._reader.read().then(_this._onRead);
        };
        this._onError = function (reason) {
            _this._flushReject(reason);
            _this._transformStreamController.error(reason);
            _this._reader.cancel(reason).catch(noop$1);
            _this._writer.abort(reason).catch(noop$1);
        };
        this._onTerminate = function () {
            _this._flushResolve();
            _this._transformStreamController.terminate();
            var error = new TypeError('TransformStream terminated');
            _this._writer.abort(error).catch(noop$1);
        };
        this._reader = reader;
        this._writer = writer;
        this._flushPromise = new Promise(function (resolve, reject) {
            _this._flushResolve = resolve;
            _this._flushReject = reject;
        });
    }
    WrappingTransformStreamTransformer.prototype.start = function (controller) {
        this._transformStreamController = controller;
        this._reader.read()
            .then(this._onRead)
            .then(this._onTerminate, this._onError);
        var readerClosed = this._reader.closed;
        if (readerClosed) {
            readerClosed
                .then(this._onTerminate, this._onError);
        }
    };
    WrappingTransformStreamTransformer.prototype.transform = function (chunk) {
        return this._writer.write(chunk);
    };
    WrappingTransformStreamTransformer.prototype.flush = function () {
        var _this = this;
        return this._writer.close()
            .then(function () { return _this._flushPromise; });
    };
    return WrappingTransformStreamTransformer;
}());

var webStreamsAdapter = /*#__PURE__*/Object.freeze({
  __proto__: null,
  createReadableStreamWrapper: createReadableStreamWrapper,
  createTransformStreamWrapper: createTransformStreamWrapper,
  createWrappingReadableSource: createWrappingReadableSource,
  createWrappingTransformer: createWrappingTransformer,
  createWrappingWritableSink: createWrappingWritableSink,
  createWritableStreamWrapper: createWritableStreamWrapper
});

var bn = createCommonjsModule(function (module) {
(function (module, exports) {

  // Utils
  function assert (val, msg) {
    if (!val) throw new Error(msg || 'Assertion failed');
  }

  // Could use `inherits` module, but don't want to move from single file
  // architecture yet.
  function inherits (ctor, superCtor) {
    ctor.super_ = superCtor;
    var TempCtor = function () {};
    TempCtor.prototype = superCtor.prototype;
    ctor.prototype = new TempCtor();
    ctor.prototype.constructor = ctor;
  }

  // BN

  function BN (number, base, endian) {
    if (BN.isBN(number)) {
      return number;
    }

    this.negative = 0;
    this.words = null;
    this.length = 0;

    // Reduction context
    this.red = null;

    if (number !== null) {
      if (base === 'le' || base === 'be') {
        endian = base;
        base = 10;
      }

      this._init(number || 0, base || 10, endian || 'be');
    }
  }
  if (typeof module === 'object') {
    module.exports = BN;
  } else {
    exports.BN = BN;
  }

  BN.BN = BN;
  BN.wordSize = 26;

  var Buffer;
  try {
    Buffer = buffer__default['default'].Buffer;
  } catch (e) {
  }

  BN.isBN = function isBN (num) {
    if (num instanceof BN) {
      return true;
    }

    return num !== null && typeof num === 'object' &&
      num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
  };

  BN.max = function max (left, right) {
    if (left.cmp(right) > 0) return left;
    return right;
  };

  BN.min = function min (left, right) {
    if (left.cmp(right) < 0) return left;
    return right;
  };

  BN.prototype._init = function init (number, base, endian) {
    if (typeof number === 'number') {
      return this._initNumber(number, base, endian);
    }

    if (typeof number === 'object') {
      return this._initArray(number, base, endian);
    }

    if (base === 'hex') {
      base = 16;
    }
    assert(base === (base | 0) && base >= 2 && base <= 36);

    number = number.toString().replace(/\s+/g, '');
    var start = 0;
    if (number[0] === '-') {
      start++;
    }

    if (base === 16) {
      this._parseHex(number, start);
    } else {
      this._parseBase(number, base, start);
    }

    if (number[0] === '-') {
      this.negative = 1;
    }

    this.strip();

    if (endian !== 'le') return;

    this._initArray(this.toArray(), base, endian);
  };

  BN.prototype._initNumber = function _initNumber (number, base, endian) {
    if (number < 0) {
      this.negative = 1;
      number = -number;
    }
    if (number < 0x4000000) {
      this.words = [ number & 0x3ffffff ];
      this.length = 1;
    } else if (number < 0x10000000000000) {
      this.words = [
        number & 0x3ffffff,
        (number / 0x4000000) & 0x3ffffff
      ];
      this.length = 2;
    } else {
      assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
      this.words = [
        number & 0x3ffffff,
        (number / 0x4000000) & 0x3ffffff,
        1
      ];
      this.length = 3;
    }

    if (endian !== 'le') return;

    // Reverse the bytes
    this._initArray(this.toArray(), base, endian);
  };

  BN.prototype._initArray = function _initArray (number, base, endian) {
    // Perhaps a Uint8Array
    assert(typeof number.length === 'number');
    if (number.length <= 0) {
      this.words = [ 0 ];
      this.length = 1;
      return this;
    }

    this.length = Math.ceil(number.length / 3);
    this.words = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
      this.words[i] = 0;
    }

    var j, w;
    var off = 0;
    if (endian === 'be') {
      for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
        w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
        this.words[j] |= (w << off) & 0x3ffffff;
        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
        off += 24;
        if (off >= 26) {
          off -= 26;
          j++;
        }
      }
    } else if (endian === 'le') {
      for (i = 0, j = 0; i < number.length; i += 3) {
        w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
        this.words[j] |= (w << off) & 0x3ffffff;
        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
        off += 24;
        if (off >= 26) {
          off -= 26;
          j++;
        }
      }
    }
    return this.strip();
  };

  function parseHex (str, start, end) {
    var r = 0;
    var len = Math.min(str.length, end);
    for (var i = start; i < len; i++) {
      var c = str.charCodeAt(i) - 48;

      r <<= 4;

      // 'a' - 'f'
      if (c >= 49 && c <= 54) {
        r |= c - 49 + 0xa;

      // 'A' - 'F'
      } else if (c >= 17 && c <= 22) {
        r |= c - 17 + 0xa;

      // '0' - '9'
      } else {
        r |= c & 0xf;
      }
    }
    return r;
  }

  BN.prototype._parseHex = function _parseHex (number, start) {
    // Create possibly bigger array to ensure that it fits the number
    this.length = Math.ceil((number.length - start) / 6);
    this.words = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
      this.words[i] = 0;
    }

    var j, w;
    // Scan 24-bit chunks and add them to the number
    var off = 0;
    for (i = number.length - 6, j = 0; i >= start; i -= 6) {
      w = parseHex(number, i, i + 6);
      this.words[j] |= (w << off) & 0x3ffffff;
      // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
      off += 24;
      if (off >= 26) {
        off -= 26;
        j++;
      }
    }
    if (i + 6 !== start) {
      w = parseHex(number, start, i + 6);
      this.words[j] |= (w << off) & 0x3ffffff;
      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
    }
    this.strip();
  };

  function parseBase (str, start, end, mul) {
    var r = 0;
    var len = Math.min(str.length, end);
    for (var i = start; i < len; i++) {
      var c = str.charCodeAt(i) - 48;

      r *= mul;

      // 'a'
      if (c >= 49) {
        r += c - 49 + 0xa;

      // 'A'
      } else if (c >= 17) {
        r += c - 17 + 0xa;

      // '0' - '9'
      } else {
        r += c;
      }
    }
    return r;
  }

  BN.prototype._parseBase = function _parseBase (number, base, start) {
    // Initialize as zero
    this.words = [ 0 ];
    this.length = 1;

    // Find length of limb in base
    for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
      limbLen++;
    }
    limbLen--;
    limbPow = (limbPow / base) | 0;

    var total = number.length - start;
    var mod = total % limbLen;
    var end = Math.min(total, total - mod) + start;

    var word = 0;
    for (var i = start; i < end; i += limbLen) {
      word = parseBase(number, i, i + limbLen, base);

      this.imuln(limbPow);
      if (this.words[0] + word < 0x4000000) {
        this.words[0] += word;
      } else {
        this._iaddn(word);
      }
    }

    if (mod !== 0) {
      var pow = 1;
      word = parseBase(number, i, number.length, base);

      for (i = 0; i < mod; i++) {
        pow *= base;
      }

      this.imuln(pow);
      if (this.words[0] + word < 0x4000000) {
        this.words[0] += word;
      } else {
        this._iaddn(word);
      }
    }
  };

  BN.prototype.copy = function copy (dest) {
    dest.words = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
      dest.words[i] = this.words[i];
    }
    dest.length = this.length;
    dest.negative = this.negative;
    dest.red = this.red;
  };

  BN.prototype.clone = function clone () {
    var r = new BN(null);
    this.copy(r);
    return r;
  };

  BN.prototype._expand = function _expand (size) {
    while (this.length < size) {
      this.words[this.length++] = 0;
    }
    return this;
  };

  // Remove leading `0` from `this`
  BN.prototype.strip = function strip () {
    while (this.length > 1 && this.words[this.length - 1] === 0) {
      this.length--;
    }
    return this._normSign();
  };

  BN.prototype._normSign = function _normSign () {
    // -0 = 0
    if (this.length === 1 && this.words[0] === 0) {
      this.negative = 0;
    }
    return this;
  };

  BN.prototype.inspect = function inspect () {
    return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
  };

  /*

  var zeros = [];
  var groupSizes = [];
  var groupBases = [];

  var s = '';
  var i = -1;
  while (++i < BN.wordSize) {
    zeros[i] = s;
    s += '0';
  }
  groupSizes[0] = 0;
  groupSizes[1] = 0;
  groupBases[0] = 0;
  groupBases[1] = 0;
  var base = 2 - 1;
  while (++base < 36 + 1) {
    var groupSize = 0;
    var groupBase = 1;
    while (groupBase < (1 << BN.wordSize) / base) {
      groupBase *= base;
      groupSize += 1;
    }
    groupSizes[base] = groupSize;
    groupBases[base] = groupBase;
  }

  */

  var zeros = [
    '',
    '0',
    '00',
    '000',
    '0000',
    '00000',
    '000000',
    '0000000',
    '00000000',
    '000000000',
    '0000000000',
    '00000000000',
    '000000000000',
    '0000000000000',
    '00000000000000',
    '000000000000000',
    '0000000000000000',
    '00000000000000000',
    '000000000000000000',
    '0000000000000000000',
    '00000000000000000000',
    '000000000000000000000',
    '0000000000000000000000',
    '00000000000000000000000',
    '000000000000000000000000',
    '0000000000000000000000000'
  ];

  var groupSizes = [
    0, 0,
    25, 16, 12, 11, 10, 9, 8,
    8, 7, 7, 7, 7, 6, 6,
    6, 6, 6, 6, 6, 5, 5,
    5, 5, 5, 5, 5, 5, 5,
    5, 5, 5, 5, 5, 5, 5
  ];

  var groupBases = [
    0, 0,
    33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
    43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
    16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
    6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
    24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
  ];

  BN.prototype.toString = function toString (base, padding) {
    base = base || 10;
    padding = padding | 0 || 1;

    var out;
    if (base === 16 || base === 'hex') {
      out = '';
      var off = 0;
      var carry = 0;
      for (var i = 0; i < this.length; i++) {
        var w = this.words[i];
        var word = (((w << off) | carry) & 0xffffff).toString(16);
        carry = (w >>> (24 - off)) & 0xffffff;
        if (carry !== 0 || i !== this.length - 1) {
          out = zeros[6 - word.length] + word + out;
        } else {
          out = word + out;
        }
        off += 2;
        if (off >= 26) {
          off -= 26;
          i--;
        }
      }
      if (carry !== 0) {
        out = carry.toString(16) + out;
      }
      while (out.length % padding !== 0) {
        out = '0' + out;
      }
      if (this.negative !== 0) {
        out = '-' + out;
      }
      return out;
    }

    if (base === (base | 0) && base >= 2 && base <= 36) {
      // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
      var groupSize = groupSizes[base];
      // var groupBase = Math.pow(base, groupSize);
      var groupBase = groupBases[base];
      out = '';
      var c = this.clone();
      c.negative = 0;
      while (!c.isZero()) {
        var r = c.modn(groupBase).toString(base);
        c = c.idivn(groupBase);

        if (!c.isZero()) {
          out = zeros[groupSize - r.length] + r + out;
        } else {
          out = r + out;
        }
      }
      if (this.isZero()) {
        out = '0' + out;
      }
      while (out.length % padding !== 0) {
        out = '0' + out;
      }
      if (this.negative !== 0) {
        out = '-' + out;
      }
      return out;
    }

    assert(false, 'Base should be between 2 and 36');
  };

  BN.prototype.toNumber = function toNumber () {
    var ret = this.words[0];
    if (this.length === 2) {
      ret += this.words[1] * 0x4000000;
    } else if (this.length === 3 && this.words[2] === 0x01) {
      // NOTE: at this stage it is known that the top bit is set
      ret += 0x10000000000000 + (this.words[1] * 0x4000000);
    } else if (this.length > 2) {
      assert(false, 'Number can only safely store up to 53 bits');
    }
    return (this.negative !== 0) ? -ret : ret;
  };

  BN.prototype.toJSON = function toJSON () {
    return this.toString(16);
  };

  BN.prototype.toBuffer = function toBuffer (endian, length) {
    assert(typeof Buffer !== 'undefined');
    return this.toArrayLike(Buffer, endian, length);
  };

  BN.prototype.toArray = function toArray (endian, length) {
    return this.toArrayLike(Array, endian, length);
  };

  BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
    var byteLength = this.byteLength();
    var reqLength = length || Math.max(1, byteLength);
    assert(byteLength <= reqLength, 'byte array longer than desired length');
    assert(reqLength > 0, 'Requested array length <= 0');

    this.strip();
    var littleEndian = endian === 'le';
    var res = new ArrayType(reqLength);

    var b, i;
    var q = this.clone();
    if (!littleEndian) {
      // Assume big-endian
      for (i = 0; i < reqLength - byteLength; i++) {
        res[i] = 0;
      }

      for (i = 0; !q.isZero(); i++) {
        b = q.andln(0xff);
        q.iushrn(8);

        res[reqLength - i - 1] = b;
      }
    } else {
      for (i = 0; !q.isZero(); i++) {
        b = q.andln(0xff);
        q.iushrn(8);

        res[i] = b;
      }

      for (; i < reqLength; i++) {
        res[i] = 0;
      }
    }

    return res;
  };

  if (Math.clz32) {
    BN.prototype._countBits = function _countBits (w) {
      return 32 - Math.clz32(w);
    };
  } else {
    BN.prototype._countBits = function _countBits (w) {
      var t = w;
      var r = 0;
      if (t >= 0x1000) {
        r += 13;
        t >>>= 13;
      }
      if (t >= 0x40) {
        r += 7;
        t >>>= 7;
      }
      if (t >= 0x8) {
        r += 4;
        t >>>= 4;
      }
      if (t >= 0x02) {
        r += 2;
        t >>>= 2;
      }
      return r + t;
    };
  }

  BN.prototype._zeroBits = function _zeroBits (w) {
    // Short-cut
    if (w === 0) return 26;

    var t = w;
    var r = 0;
    if ((t & 0x1fff) === 0) {
      r += 13;
      t >>>= 13;
    }
    if ((t & 0x7f) === 0) {
      r += 7;
      t >>>= 7;
    }
    if ((t & 0xf) === 0) {
      r += 4;
      t >>>= 4;
    }
    if ((t & 0x3) === 0) {
      r += 2;
      t >>>= 2;
    }
    if ((t & 0x1) === 0) {
      r++;
    }
    return r;
  };

  // Return number of used bits in a BN
  BN.prototype.bitLength = function bitLength () {
    var w = this.words[this.length - 1];
    var hi = this._countBits(w);
    return (this.length - 1) * 26 + hi;
  };

  function toBitArray (num) {
    var w = new Array(num.bitLength());

    for (var bit = 0; bit < w.length; bit++) {
      var off = (bit / 26) | 0;
      var wbit = bit % 26;

      w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
    }

    return w;
  }

  // Number of trailing zero bits
  BN.prototype.zeroBits = function zeroBits () {
    if (this.isZero()) return 0;

    var r = 0;
    for (var i = 0; i < this.length; i++) {
      var b = this._zeroBits(this.words[i]);
      r += b;
      if (b !== 26) break;
    }
    return r;
  };

  BN.prototype.byteLength = function byteLength () {
    return Math.ceil(this.bitLength() / 8);
  };

  BN.prototype.toTwos = function toTwos (width) {
    if (this.negative !== 0) {
      return this.abs().inotn(width).iaddn(1);
    }
    return this.clone();
  };

  BN.prototype.fromTwos = function fromTwos (width) {
    if (this.testn(width - 1)) {
      return this.notn(width).iaddn(1).ineg();
    }
    return this.clone();
  };

  BN.prototype.isNeg = function isNeg () {
    return this.negative !== 0;
  };

  // Return negative clone of `this`
  BN.prototype.neg = function neg () {
    return this.clone().ineg();
  };

  BN.prototype.ineg = function ineg () {
    if (!this.isZero()) {
      this.negative ^= 1;
    }

    return this;
  };

  // Or `num` with `this` in-place
  BN.prototype.iuor = function iuor (num) {
    while (this.length < num.length) {
      this.words[this.length++] = 0;
    }

    for (var i = 0; i < num.length; i++) {
      this.words[i] = this.words[i] | num.words[i];
    }

    return this.strip();
  };

  BN.prototype.ior = function ior (num) {
    assert((this.negative | num.negative) === 0);
    return this.iuor(num);
  };

  // Or `num` with `this`
  BN.prototype.or = function or (num) {
    if (this.length > num.length) return this.clone().ior(num);
    return num.clone().ior(this);
  };

  BN.prototype.uor = function uor (num) {
    if (this.length > num.length) return this.clone().iuor(num);
    return num.clone().iuor(this);
  };

  // And `num` with `this` in-place
  BN.prototype.iuand = function iuand (num) {
    // b = min-length(num, this)
    var b;
    if (this.length > num.length) {
      b = num;
    } else {
      b = this;
    }

    for (var i = 0; i < b.length; i++) {
      this.words[i] = this.words[i] & num.words[i];
    }

    this.length = b.length;

    return this.strip();
  };

  BN.prototype.iand = function iand (num) {
    assert((this.negative | num.negative) === 0);
    return this.iuand(num);
  };

  // And `num` with `this`
  BN.prototype.and = function and (num) {
    if (this.length > num.length) return this.clone().iand(num);
    return num.clone().iand(this);
  };

  BN.prototype.uand = function uand (num) {
    if (this.length > num.length) return this.clone().iuand(num);
    return num.clone().iuand(this);
  };

  // Xor `num` with `this` in-place
  BN.prototype.iuxor = function iuxor (num) {
    // a.length > b.length
    var a;
    var b;
    if (this.length > num.length) {
      a = this;
      b = num;
    } else {
      a = num;
      b = this;
    }

    for (var i = 0; i < b.length; i++) {
      this.words[i] = a.words[i] ^ b.words[i];
    }

    if (this !== a) {
      for (; i < a.length; i++) {
        this.words[i] = a.words[i];
      }
    }

    this.length = a.length;

    return this.strip();
  };

  BN.prototype.ixor = function ixor (num) {
    assert((this.negative | num.negative) === 0);
    return this.iuxor(num);
  };

  // Xor `num` with `this`
  BN.prototype.xor = function xor (num) {
    if (this.length > num.length) return this.clone().ixor(num);
    return num.clone().ixor(this);
  };

  BN.prototype.uxor = function uxor (num) {
    if (this.length > num.length) return this.clone().iuxor(num);
    return num.clone().iuxor(this);
  };

  // Not ``this`` with ``width`` bitwidth
  BN.prototype.inotn = function inotn (width) {
    assert(typeof width === 'number' && width >= 0);

    var bytesNeeded = Math.ceil(width / 26) | 0;
    var bitsLeft = width % 26;

    // Extend the buffer with leading zeroes
    this._expand(bytesNeeded);

    if (bitsLeft > 0) {
      bytesNeeded--;
    }

    // Handle complete words
    for (var i = 0; i < bytesNeeded; i++) {
      this.words[i] = ~this.words[i] & 0x3ffffff;
    }

    // Handle the residue
    if (bitsLeft > 0) {
      this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
    }

    // And remove leading zeroes
    return this.strip();
  };

  BN.prototype.notn = function notn (width) {
    return this.clone().inotn(width);
  };

  // Set `bit` of `this`
  BN.prototype.setn = function setn (bit, val) {
    assert(typeof bit === 'number' && bit >= 0);

    var off = (bit / 26) | 0;
    var wbit = bit % 26;

    this._expand(off + 1);

    if (val) {
      this.words[off] = this.words[off] | (1 << wbit);
    } else {
      this.words[off] = this.words[off] & ~(1 << wbit);
    }

    return this.strip();
  };

  // Add `num` to `this` in-place
  BN.prototype.iadd = function iadd (num) {
    var r;

    // negative + positive
    if (this.negative !== 0 && num.negative === 0) {
      this.negative = 0;
      r = this.isub(num);
      this.negative ^= 1;
      return this._normSign();

    // positive + negative
    } else if (this.negative === 0 && num.negative !== 0) {
      num.negative = 0;
      r = this.isub(num);
      num.negative = 1;
      return r._normSign();
    }

    // a.length > b.length
    var a, b;
    if (this.length > num.length) {
      a = this;
      b = num;
    } else {
      a = num;
      b = this;
    }

    var carry = 0;
    for (var i = 0; i < b.length; i++) {
      r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
      this.words[i] = r & 0x3ffffff;
      carry = r >>> 26;
    }
    for (; carry !== 0 && i < a.length; i++) {
      r = (a.words[i] | 0) + carry;
      this.words[i] = r & 0x3ffffff;
      carry = r >>> 26;
    }

    this.length = a.length;
    if (carry !== 0) {
      this.words[this.length] = carry;
      this.length++;
    // Copy the rest of the words
    } else if (a !== this) {
      for (; i < a.length; i++) {
        this.words[i] = a.words[i];
      }
    }

    return this;
  };

  // Add `num` to `this`
  BN.prototype.add = function add (num) {
    var res;
    if (num.negative !== 0 && this.negative === 0) {
      num.negative = 0;
      res = this.sub(num);
      num.negative ^= 1;
      return res;
    } else if (num.negative === 0 && this.negative !== 0) {
      this.negative = 0;
      res = num.sub(this);
      this.negative = 1;
      return res;
    }

    if (this.length > num.length) return this.clone().iadd(num);

    return num.clone().iadd(this);
  };

  // Subtract `num` from `this` in-place
  BN.prototype.isub = function isub (num) {
    // this - (-num) = this + num
    if (num.negative !== 0) {
      num.negative = 0;
      var r = this.iadd(num);
      num.negative = 1;
      return r._normSign();

    // -this - num = -(this + num)
    } else if (this.negative !== 0) {
      this.negative = 0;
      this.iadd(num);
      this.negative = 1;
      return this._normSign();
    }

    // At this point both numbers are positive
    var cmp = this.cmp(num);

    // Optimization - zeroify
    if (cmp === 0) {
      this.negative = 0;
      this.length = 1;
      this.words[0] = 0;
      return this;
    }

    // a > b
    var a, b;
    if (cmp > 0) {
      a = this;
      b = num;
    } else {
      a = num;
      b = this;
    }

    var carry = 0;
    for (var i = 0; i < b.length; i++) {
      r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
      carry = r >> 26;
      this.words[i] = r & 0x3ffffff;
    }
    for (; carry !== 0 && i < a.length; i++) {
      r = (a.words[i] | 0) + carry;
      carry = r >> 26;
      this.words[i] = r & 0x3ffffff;
    }

    // Copy rest of the words
    if (carry === 0 && i < a.length && a !== this) {
      for (; i < a.length; i++) {
        this.words[i] = a.words[i];
      }
    }

    this.length = Math.max(this.length, i);

    if (a !== this) {
      this.negative = 1;
    }

    return this.strip();
  };

  // Subtract `num` from `this`
  BN.prototype.sub = function sub (num) {
    return this.clone().isub(num);
  };

  function smallMulTo (self, num, out) {
    out.negative = num.negative ^ self.negative;
    var len = (self.length + num.length) | 0;
    out.length = len;
    len = (len - 1) | 0;

    // Peel one iteration (compiler can't do it, because of code complexity)
    var a = self.words[0] | 0;
    var b = num.words[0] | 0;
    var r = a * b;

    var lo = r & 0x3ffffff;
    var carry = (r / 0x4000000) | 0;
    out.words[0] = lo;

    for (var k = 1; k < len; k++) {
      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
      // note that ncarry could be >= 0x3ffffff
      var ncarry = carry >>> 26;
      var rword = carry & 0x3ffffff;
      var maxJ = Math.min(k, num.length - 1);
      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
        var i = (k - j) | 0;
        a = self.words[i] | 0;
        b = num.words[j] | 0;
        r = a * b + rword;
        ncarry += (r / 0x4000000) | 0;
        rword = r & 0x3ffffff;
      }
      out.words[k] = rword | 0;
      carry = ncarry | 0;
    }
    if (carry !== 0) {
      out.words[k] = carry | 0;
    } else {
      out.length--;
    }

    return out.strip();
  }

  // TODO(indutny): it may be reasonable to omit it for users who don't need
  // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
  // multiplication (like elliptic secp256k1).
  var comb10MulTo = function comb10MulTo (self, num, out) {
    var a = self.words;
    var b = num.words;
    var o = out.words;
    var c = 0;
    var lo;
    var mid;
    var hi;
    var a0 = a[0] | 0;
    var al0 = a0 & 0x1fff;
    var ah0 = a0 >>> 13;
    var a1 = a[1] | 0;
    var al1 = a1 & 0x1fff;
    var ah1 = a1 >>> 13;
    var a2 = a[2] | 0;
    var al2 = a2 & 0x1fff;
    var ah2 = a2 >>> 13;
    var a3 = a[3] | 0;
    var al3 = a3 & 0x1fff;
    var ah3 = a3 >>> 13;
    var a4 = a[4] | 0;
    var al4 = a4 & 0x1fff;
    var ah4 = a4 >>> 13;
    var a5 = a[5] | 0;
    var al5 = a5 & 0x1fff;
    var ah5 = a5 >>> 13;
    var a6 = a[6] | 0;
    var al6 = a6 & 0x1fff;
    var ah6 = a6 >>> 13;
    var a7 = a[7] | 0;
    var al7 = a7 & 0x1fff;
    var ah7 = a7 >>> 13;
    var a8 = a[8] | 0;
    var al8 = a8 & 0x1fff;
    var ah8 = a8 >>> 13;
    var a9 = a[9] | 0;
    var al9 = a9 & 0x1fff;
    var ah9 = a9 >>> 13;
    var b0 = b[0] | 0;
    var bl0 = b0 & 0x1fff;
    var bh0 = b0 >>> 13;
    var b1 = b[1] | 0;
    var bl1 = b1 & 0x1fff;
    var bh1 = b1 >>> 13;
    var b2 = b[2] | 0;
    var bl2 = b2 & 0x1fff;
    var bh2 = b2 >>> 13;
    var b3 = b[3] | 0;
    var bl3 = b3 & 0x1fff;
    var bh3 = b3 >>> 13;
    var b4 = b[4] | 0;
    var bl4 = b4 & 0x1fff;
    var bh4 = b4 >>> 13;
    var b5 = b[5] | 0;
    var bl5 = b5 & 0x1fff;
    var bh5 = b5 >>> 13;
    var b6 = b[6] | 0;
    var bl6 = b6 & 0x1fff;
    var bh6 = b6 >>> 13;
    var b7 = b[7] | 0;
    var bl7 = b7 & 0x1fff;
    var bh7 = b7 >>> 13;
    var b8 = b[8] | 0;
    var bl8 = b8 & 0x1fff;
    var bh8 = b8 >>> 13;
    var b9 = b[9] | 0;
    var bl9 = b9 & 0x1fff;
    var bh9 = b9 >>> 13;

    out.negative = self.negative ^ num.negative;
    out.length = 19;
    /* k = 0 */
    lo = Math.imul(al0, bl0);
    mid = Math.imul(al0, bh0);
    mid = (mid + Math.imul(ah0, bl0)) | 0;
    hi = Math.imul(ah0, bh0);
    var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
    w0 &= 0x3ffffff;
    /* k = 1 */
    lo = Math.imul(al1, bl0);
    mid = Math.imul(al1, bh0);
    mid = (mid + Math.imul(ah1, bl0)) | 0;
    hi = Math.imul(ah1, bh0);
    lo = (lo + Math.imul(al0, bl1)) | 0;
    mid = (mid + Math.imul(al0, bh1)) | 0;
    mid = (mid + Math.imul(ah0, bl1)) | 0;
    hi = (hi + Math.imul(ah0, bh1)) | 0;
    var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
    w1 &= 0x3ffffff;
    /* k = 2 */
    lo = Math.imul(al2, bl0);
    mid = Math.imul(al2, bh0);
    mid = (mid + Math.imul(ah2, bl0)) | 0;
    hi = Math.imul(ah2, bh0);
    lo = (lo + Math.imul(al1, bl1)) | 0;
    mid = (mid + Math.imul(al1, bh1)) | 0;
    mid = (mid + Math.imul(ah1, bl1)) | 0;
    hi = (hi + Math.imul(ah1, bh1)) | 0;
    lo = (lo + Math.imul(al0, bl2)) | 0;
    mid = (mid + Math.imul(al0, bh2)) | 0;
    mid = (mid + Math.imul(ah0, bl2)) | 0;
    hi = (hi + Math.imul(ah0, bh2)) | 0;
    var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
    w2 &= 0x3ffffff;
    /* k = 3 */
    lo = Math.imul(al3, bl0);
    mid = Math.imul(al3, bh0);
    mid = (mid + Math.imul(ah3, bl0)) | 0;
    hi = Math.imul(ah3, bh0);
    lo = (lo + Math.imul(al2, bl1)) | 0;
    mid = (mid + Math.imul(al2, bh1)) | 0;
    mid = (mid + Math.imul(ah2, bl1)) | 0;
    hi = (hi + Math.imul(ah2, bh1)) | 0;
    lo = (lo + Math.imul(al1, bl2)) | 0;
    mid = (mid + Math.imul(al1, bh2)) | 0;
    mid = (mid + Math.imul(ah1, bl2)) | 0;
    hi = (hi + Math.imul(ah1, bh2)) | 0;
    lo = (lo + Math.imul(al0, bl3)) | 0;
    mid = (mid + Math.imul(al0, bh3)) | 0;
    mid = (mid + Math.imul(ah0, bl3)) | 0;
    hi = (hi + Math.imul(ah0, bh3)) | 0;
    var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
    w3 &= 0x3ffffff;
    /* k = 4 */
    lo = Math.imul(al4, bl0);
    mid = Math.imul(al4, bh0);
    mid = (mid + Math.imul(ah4, bl0)) | 0;
    hi = Math.imul(ah4, bh0);
    lo = (lo + Math.imul(al3, bl1)) | 0;
    mid = (mid + Math.imul(al3, bh1)) | 0;
    mid = (mid + Math.imul(ah3, bl1)) | 0;
    hi = (hi + Math.imul(ah3, bh1)) | 0;
    lo = (lo + Math.imul(al2, bl2)) | 0;
    mid = (mid + Math.imul(al2, bh2)) | 0;
    mid = (mid + Math.imul(ah2, bl2)) | 0;
    hi = (hi + Math.imul(ah2, bh2)) | 0;
    lo = (lo + Math.imul(al1, bl3)) | 0;
    mid = (mid + Math.imul(al1, bh3)) | 0;
    mid = (mid + Math.imul(ah1, bl3)) | 0;
    hi = (hi + Math.imul(ah1, bh3)) | 0;
    lo = (lo + Math.imul(al0, bl4)) | 0;
    mid = (mid + Math.imul(al0, bh4)) | 0;
    mid = (mid + Math.imul(ah0, bl4)) | 0;
    hi = (hi + Math.imul(ah0, bh4)) | 0;
    var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
    w4 &= 0x3ffffff;
    /* k = 5 */
    lo = Math.imul(al5, bl0);
    mid = Math.imul(al5, bh0);
    mid = (mid + Math.imul(ah5, bl0)) | 0;
    hi = Math.imul(ah5, bh0);
    lo = (lo + Math.imul(al4, bl1)) | 0;
    mid = (mid + Math.imul(al4, bh1)) | 0;
    mid = (mid + Math.imul(ah4, bl1)) | 0;
    hi = (hi + Math.imul(ah4, bh1)) | 0;
    lo = (lo + Math.imul(al3, bl2)) | 0;
    mid = (mid + Math.imul(al3, bh2)) | 0;
    mid = (mid + Math.imul(ah3, bl2)) | 0;
    hi = (hi + Math.imul(ah3, bh2)) | 0;
    lo = (lo + Math.imul(al2, bl3)) | 0;
    mid = (mid + Math.imul(al2, bh3)) | 0;
    mid = (mid + Math.imul(ah2, bl3)) | 0;
    hi = (hi + Math.imul(ah2, bh3)) | 0;
    lo = (lo + Math.imul(al1, bl4)) | 0;
    mid = (mid + Math.imul(al1, bh4)) | 0;
    mid = (mid + Math.imul(ah1, bl4)) | 0;
    hi = (hi + Math.imul(ah1, bh4)) | 0;
    lo = (lo + Math.imul(al0, bl5)) | 0;
    mid = (mid + Math.imul(al0, bh5)) | 0;
    mid = (mid + Math.imul(ah0, bl5)) | 0;
    hi = (hi + Math.imul(ah0, bh5)) | 0;
    var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
    w5 &= 0x3ffffff;
    /* k = 6 */
    lo = Math.imul(al6, bl0);
    mid = Math.imul(al6, bh0);
    mid = (mid + Math.imul(ah6, bl0)) | 0;
    hi = Math.imul(ah6, bh0);
    lo = (lo + Math.imul(al5, bl1)) | 0;
    mid = (mid + Math.imul(al5, bh1)) | 0;
    mid = (mid + Math.imul(ah5, bl1)) | 0;
    hi = (hi + Math.imul(ah5, bh1)) | 0;
    lo = (lo + Math.imul(al4, bl2)) | 0;
    mid = (mid + Math.imul(al4, bh2)) | 0;
    mid = (mid + Math.imul(ah4, bl2)) | 0;
    hi = (hi + Math.imul(ah4, bh2)) | 0;
    lo = (lo + Math.imul(al3, bl3)) | 0;
    mid = (mid + Math.imul(al3, bh3)) | 0;
    mid = (mid + Math.imul(ah3, bl3)) | 0;
    hi = (hi + Math.imul(ah3, bh3)) | 0;
    lo = (lo + Math.imul(al2, bl4)) | 0;
    mid = (mid + Math.imul(al2, bh4)) | 0;
    mid = (mid + Math.imul(ah2, bl4)) | 0;
    hi = (hi + Math.imul(ah2, bh4)) | 0;
    lo = (lo + Math.imul(al1, bl5)) | 0;
    mid = (mid + Math.imul(al1, bh5)) | 0;
    mid = (mid + Math.imul(ah1, bl5)) | 0;
    hi = (hi + Math.imul(ah1, bh5)) | 0;
    lo = (lo + Math.imul(al0, bl6)) | 0;
    mid = (mid + Math.imul(al0, bh6)) | 0;
    mid = (mid + Math.imul(ah0, bl6)) | 0;
    hi = (hi + Math.imul(ah0, bh6)) | 0;
    var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
    w6 &= 0x3ffffff;
    /* k = 7 */
    lo = Math.imul(al7, bl0);
    mid = Math.imul(al7, bh0);
    mid = (mid + Math.imul(ah7, bl0)) | 0;
    hi = Math.imul(ah7, bh0);
    lo = (lo + Math.imul(al6, bl1)) | 0;
    mid = (mid + Math.imul(al6, bh1)) | 0;
    mid = (mid + Math.imul(ah6, bl1)) | 0;
    hi = (hi + Math.imul(ah6, bh1)) | 0;
    lo = (lo + Math.imul(al5, bl2)) | 0;
    mid = (mid + Math.imul(al5, bh2)) | 0;
    mid = (mid + Math.imul(ah5, bl2)) | 0;
    hi = (hi + Math.imul(ah5, bh2)) | 0;
    lo = (lo + Math.imul(al4, bl3)) | 0;
    mid = (mid + Math.imul(al4, bh3)) | 0;
    mid = (mid + Math.imul(ah4, bl3)) | 0;
    hi = (hi + Math.imul(ah4, bh3)) | 0;
    lo = (lo + Math.imul(al3, bl4)) | 0;
    mid = (mid + Math.imul(al3, bh4)) | 0;
    mid = (mid + Math.imul(ah3, bl4)) | 0;
    hi = (hi + Math.imul(ah3, bh4)) | 0;
    lo = (lo + Math.imul(al2, bl5)) | 0;
    mid = (mid + Math.imul(al2, bh5)) | 0;
    mid = (mid + Math.imul(ah2, bl5)) | 0;
    hi = (hi + Math.imul(ah2, bh5)) | 0;
    lo = (lo + Math.imul(al1, bl6)) | 0;
    mid = (mid + Math.imul(al1, bh6)) | 0;
    mid = (mid + Math.imul(ah1, bl6)) | 0;
    hi = (hi + Math.imul(ah1, bh6)) | 0;
    lo = (lo + Math.imul(al0, bl7)) | 0;
    mid = (mid + Math.imul(al0, bh7)) | 0;
    mid = (mid + Math.imul(ah0, bl7)) | 0;
    hi = (hi + Math.imul(ah0, bh7)) | 0;
    var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
    w7 &= 0x3ffffff;
    /* k = 8 */
    lo = Math.imul(al8, bl0);
    mid = Math.imul(al8, bh0);
    mid = (mid + Math.imul(ah8, bl0)) | 0;
    hi = Math.imul(ah8, bh0);
    lo = (lo + Math.imul(al7, bl1)) | 0;
    mid = (mid + Math.imul(al7, bh1)) | 0;
    mid = (mid + Math.imul(ah7, bl1)) | 0;
    hi = (hi + Math.imul(ah7, bh1)) | 0;
    lo = (lo + Math.imul(al6, bl2)) | 0;
    mid = (mid + Math.imul(al6, bh2)) | 0;
    mid = (mid + Math.imul(ah6, bl2)) | 0;
    hi = (hi + Math.imul(ah6, bh2)) | 0;
    lo = (lo + Math.imul(al5, bl3)) | 0;
    mid = (mid + Math.imul(al5, bh3)) | 0;
    mid = (mid + Math.imul(ah5, bl3)) | 0;
    hi = (hi + Math.imul(ah5, bh3)) | 0;
    lo = (lo + Math.imul(al4, bl4)) | 0;
    mid = (mid + Math.imul(al4, bh4)) | 0;
    mid = (mid + Math.imul(ah4, bl4)) | 0;
    hi = (hi + Math.imul(ah4, bh4)) | 0;
    lo = (lo + Math.imul(al3, bl5)) | 0;
    mid = (mid + Math.imul(al3, bh5)) | 0;
    mid = (mid + Math.imul(ah3, bl5)) | 0;
    hi = (hi + Math.imul(ah3, bh5)) | 0;
    lo = (lo + Math.imul(al2, bl6)) | 0;
    mid = (mid + Math.imul(al2, bh6)) | 0;
    mid = (mid + Math.imul(ah2, bl6)) | 0;
    hi = (hi + Math.imul(ah2, bh6)) | 0;
    lo = (lo + Math.imul(al1, bl7)) | 0;
    mid = (mid + Math.imul(al1, bh7)) | 0;
    mid = (mid + Math.imul(ah1, bl7)) | 0;
    hi = (hi + Math.imul(ah1, bh7)) | 0;
    lo = (lo + Math.imul(al0, bl8)) | 0;
    mid = (mid + Math.imul(al0, bh8)) | 0;
    mid = (mid + Math.imul(ah0, bl8)) | 0;
    hi = (hi + Math.imul(ah0, bh8)) | 0;
    var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
    w8 &= 0x3ffffff;
    /* k = 9 */
    lo = Math.imul(al9, bl0);
    mid = Math.imul(al9, bh0);
    mid = (mid + Math.imul(ah9, bl0)) | 0;
    hi = Math.imul(ah9, bh0);
    lo = (lo + Math.imul(al8, bl1)) | 0;
    mid = (mid + Math.imul(al8, bh1)) | 0;
    mid = (mid + Math.imul(ah8, bl1)) | 0;
    hi = (hi + Math.imul(ah8, bh1)) | 0;
    lo = (lo + Math.imul(al7, bl2)) | 0;
    mid = (mid + Math.imul(al7, bh2)) | 0;
    mid = (mid + Math.imul(ah7, bl2)) | 0;
    hi = (hi + Math.imul(ah7, bh2)) | 0;
    lo = (lo + Math.imul(al6, bl3)) | 0;
    mid = (mid + Math.imul(al6, bh3)) | 0;
    mid = (mid + Math.imul(ah6, bl3)) | 0;
    hi = (hi + Math.imul(ah6, bh3)) | 0;
    lo = (lo + Math.imul(al5, bl4)) | 0;
    mid = (mid + Math.imul(al5, bh4)) | 0;
    mid = (mid + Math.imul(ah5, bl4)) | 0;
    hi = (hi + Math.imul(ah5, bh4)) | 0;
    lo = (lo + Math.imul(al4, bl5)) | 0;
    mid = (mid + Math.imul(al4, bh5)) | 0;
    mid = (mid + Math.imul(ah4, bl5)) | 0;
    hi = (hi + Math.imul(ah4, bh5)) | 0;
    lo = (lo + Math.imul(al3, bl6)) | 0;
    mid = (mid + Math.imul(al3, bh6)) | 0;
    mid = (mid + Math.imul(ah3, bl6)) | 0;
    hi = (hi + Math.imul(ah3, bh6)) | 0;
    lo = (lo + Math.imul(al2, bl7)) | 0;
    mid = (mid + Math.imul(al2, bh7)) | 0;
    mid = (mid + Math.imul(ah2, bl7)) | 0;
    hi = (hi + Math.imul(ah2, bh7)) | 0;
    lo = (lo + Math.imul(al1, bl8)) | 0;
    mid = (mid + Math.imul(al1, bh8)) | 0;
    mid = (mid + Math.imul(ah1, bl8)) | 0;
    hi = (hi + Math.imul(ah1, bh8)) | 0;
    lo = (lo + Math.imul(al0, bl9)) | 0;
    mid = (mid + Math.imul(al0, bh9)) | 0;
    mid = (mid + Math.imul(ah0, bl9)) | 0;
    hi = (hi + Math.imul(ah0, bh9)) | 0;
    var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
    w9 &= 0x3ffffff;
    /* k = 10 */
    lo = Math.imul(al9, bl1);
    mid = Math.imul(al9, bh1);
    mid = (mid + Math.imul(ah9, bl1)) | 0;
    hi = Math.imul(ah9, bh1);
    lo = (lo + Math.imul(al8, bl2)) | 0;
    mid = (mid + Math.imul(al8, bh2)) | 0;
    mid = (mid + Math.imul(ah8, bl2)) | 0;
    hi = (hi + Math.imul(ah8, bh2)) | 0;
    lo = (lo + Math.imul(al7, bl3)) | 0;
    mid = (mid + Math.imul(al7, bh3)) | 0;
    mid = (mid + Math.imul(ah7, bl3)) | 0;
    hi = (hi + Math.imul(ah7, bh3)) | 0;
    lo = (lo + Math.imul(al6, bl4)) | 0;
    mid = (mid + Math.imul(al6, bh4)) | 0;
    mid = (mid + Math.imul(ah6, bl4)) | 0;
    hi = (hi + Math.imul(ah6, bh4)) | 0;
    lo = (lo + Math.imul(al5, bl5)) | 0;
    mid = (mid + Math.imul(al5, bh5)) | 0;
    mid = (mid + Math.imul(ah5, bl5)) | 0;
    hi = (hi + Math.imul(ah5, bh5)) | 0;
    lo = (lo + Math.imul(al4, bl6)) | 0;
    mid = (mid + Math.imul(al4, bh6)) | 0;
    mid = (mid + Math.imul(ah4, bl6)) | 0;
    hi = (hi + Math.imul(ah4, bh6)) | 0;
    lo = (lo + Math.imul(al3, bl7)) | 0;
    mid = (mid + Math.imul(al3, bh7)) | 0;
    mid = (mid + Math.imul(ah3, bl7)) | 0;
    hi = (hi + Math.imul(ah3, bh7)) | 0;
    lo = (lo + Math.imul(al2, bl8)) | 0;
    mid = (mid + Math.imul(al2, bh8)) | 0;
    mid = (mid + Math.imul(ah2, bl8)) | 0;
    hi = (hi + Math.imul(ah2, bh8)) | 0;
    lo = (lo + Math.imul(al1, bl9)) | 0;
    mid = (mid + Math.imul(al1, bh9)) | 0;
    mid = (mid + Math.imul(ah1, bl9)) | 0;
    hi = (hi + Math.imul(ah1, bh9)) | 0;
    var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
    w10 &= 0x3ffffff;
    /* k = 11 */
    lo = Math.imul(al9, bl2);
    mid = Math.imul(al9, bh2);
    mid = (mid + Math.imul(ah9, bl2)) | 0;
    hi = Math.imul(ah9, bh2);
    lo = (lo + Math.imul(al8, bl3)) | 0;
    mid = (mid + Math.imul(al8, bh3)) | 0;
    mid = (mid + Math.imul(ah8, bl3)) | 0;
    hi = (hi + Math.imul(ah8, bh3)) | 0;
    lo = (lo + Math.imul(al7, bl4)) | 0;
    mid = (mid + Math.imul(al7, bh4)) | 0;
    mid = (mid + Math.imul(ah7, bl4)) | 0;
    hi = (hi + Math.imul(ah7, bh4)) | 0;
    lo = (lo + Math.imul(al6, bl5)) | 0;
    mid = (mid + Math.imul(al6, bh5)) | 0;
    mid = (mid + Math.imul(ah6, bl5)) | 0;
    hi = (hi + Math.imul(ah6, bh5)) | 0;
    lo = (lo + Math.imul(al5, bl6)) | 0;
    mid = (mid + Math.imul(al5, bh6)) | 0;
    mid = (mid + Math.imul(ah5, bl6)) | 0;
    hi = (hi + Math.imul(ah5, bh6)) | 0;
    lo = (lo + Math.imul(al4, bl7)) | 0;
    mid = (mid + Math.imul(al4, bh7)) | 0;
    mid = (mid + Math.imul(ah4, bl7)) | 0;
    hi = (hi + Math.imul(ah4, bh7)) | 0;
    lo = (lo + Math.imul(al3, bl8)) | 0;
    mid = (mid + Math.imul(al3, bh8)) | 0;
    mid = (mid + Math.imul(ah3, bl8)) | 0;
    hi = (hi + Math.imul(ah3, bh8)) | 0;
    lo = (lo + Math.imul(al2, bl9)) | 0;
    mid = (mid + Math.imul(al2, bh9)) | 0;
    mid = (mid + Math.imul(ah2, bl9)) | 0;
    hi = (hi + Math.imul(ah2, bh9)) | 0;
    var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
    w11 &= 0x3ffffff;
    /* k = 12 */
    lo = Math.imul(al9, bl3);
    mid = Math.imul(al9, bh3);
    mid = (mid + Math.imul(ah9, bl3)) | 0;
    hi = Math.imul(ah9, bh3);
    lo = (lo + Math.imul(al8, bl4)) | 0;
    mid = (mid + Math.imul(al8, bh4)) | 0;
    mid = (mid + Math.imul(ah8, bl4)) | 0;
    hi = (hi + Math.imul(ah8, bh4)) | 0;
    lo = (lo + Math.imul(al7, bl5)) | 0;
    mid = (mid + Math.imul(al7, bh5)) | 0;
    mid = (mid + Math.imul(ah7, bl5)) | 0;
    hi = (hi + Math.imul(ah7, bh5)) | 0;
    lo = (lo + Math.imul(al6, bl6)) | 0;
    mid = (mid + Math.imul(al6, bh6)) | 0;
    mid = (mid + Math.imul(ah6, bl6)) | 0;
    hi = (hi + Math.imul(ah6, bh6)) | 0;
    lo = (lo + Math.imul(al5, bl7)) | 0;
    mid = (mid + Math.imul(al5, bh7)) | 0;
    mid = (mid + Math.imul(ah5, bl7)) | 0;
    hi = (hi + Math.imul(ah5, bh7)) | 0;
    lo = (lo + Math.imul(al4, bl8)) | 0;
    mid = (mid + Math.imul(al4, bh8)) | 0;
    mid = (mid + Math.imul(ah4, bl8)) | 0;
    hi = (hi + Math.imul(ah4, bh8)) | 0;
    lo = (lo + Math.imul(al3, bl9)) | 0;
    mid = (mid + Math.imul(al3, bh9)) | 0;
    mid = (mid + Math.imul(ah3, bl9)) | 0;
    hi = (hi + Math.imul(ah3, bh9)) | 0;
    var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
    w12 &= 0x3ffffff;
    /* k = 13 */
    lo = Math.imul(al9, bl4);
    mid = Math.imul(al9, bh4);
    mid = (mid + Math.imul(ah9, bl4)) | 0;
    hi = Math.imul(ah9, bh4);
    lo = (lo + Math.imul(al8, bl5)) | 0;
    mid = (mid + Math.imul(al8, bh5)) | 0;
    mid = (mid + Math.imul(ah8, bl5)) | 0;
    hi = (hi + Math.imul(ah8, bh5)) | 0;
    lo = (lo + Math.imul(al7, bl6)) | 0;
    mid = (mid + Math.imul(al7, bh6)) | 0;
    mid = (mid + Math.imul(ah7, bl6)) | 0;
    hi = (hi + Math.imul(ah7, bh6)) | 0;
    lo = (lo + Math.imul(al6, bl7)) | 0;
    mid = (mid + Math.imul(al6, bh7)) | 0;
    mid = (mid + Math.imul(ah6, bl7)) | 0;
    hi = (hi + Math.imul(ah6, bh7)) | 0;
    lo = (lo + Math.imul(al5, bl8)) | 0;
    mid = (mid + Math.imul(al5, bh8)) | 0;
    mid = (mid + Math.imul(ah5, bl8)) | 0;
    hi = (hi + Math.imul(ah5, bh8)) | 0;
    lo = (lo + Math.imul(al4, bl9)) | 0;
    mid = (mid + Math.imul(al4, bh9)) | 0;
    mid = (mid + Math.imul(ah4, bl9)) | 0;
    hi = (hi + Math.imul(ah4, bh9)) | 0;
    var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
    w13 &= 0x3ffffff;
    /* k = 14 */
    lo = Math.imul(al9, bl5);
    mid = Math.imul(al9, bh5);
    mid = (mid + Math.imul(ah9, bl5)) | 0;
    hi = Math.imul(ah9, bh5);
    lo = (lo + Math.imul(al8, bl6)) | 0;
    mid = (mid + Math.imul(al8, bh6)) | 0;
    mid = (mid + Math.imul(ah8, bl6)) | 0;
    hi = (hi + Math.imul(ah8, bh6)) | 0;
    lo = (lo + Math.imul(al7, bl7)) | 0;
    mid = (mid + Math.imul(al7, bh7)) | 0;
    mid = (mid + Math.imul(ah7, bl7)) | 0;
    hi = (hi + Math.imul(ah7, bh7)) | 0;
    lo = (lo + Math.imul(al6, bl8)) | 0;
    mid = (mid + Math.imul(al6, bh8)) | 0;
    mid = (mid + Math.imul(ah6, bl8)) | 0;
    hi = (hi + Math.imul(ah6, bh8)) | 0;
    lo = (lo + Math.imul(al5, bl9)) | 0;
    mid = (mid + Math.imul(al5, bh9)) | 0;
    mid = (mid + Math.imul(ah5, bl9)) | 0;
    hi = (hi + Math.imul(ah5, bh9)) | 0;
    var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
    w14 &= 0x3ffffff;
    /* k = 15 */
    lo = Math.imul(al9, bl6);
    mid = Math.imul(al9, bh6);
    mid = (mid + Math.imul(ah9, bl6)) | 0;
    hi = Math.imul(ah9, bh6);
    lo = (lo + Math.imul(al8, bl7)) | 0;
    mid = (mid + Math.imul(al8, bh7)) | 0;
    mid = (mid + Math.imul(ah8, bl7)) | 0;
    hi = (hi + Math.imul(ah8, bh7)) | 0;
    lo = (lo + Math.imul(al7, bl8)) | 0;
    mid = (mid + Math.imul(al7, bh8)) | 0;
    mid = (mid + Math.imul(ah7, bl8)) | 0;
    hi = (hi + Math.imul(ah7, bh8)) | 0;
    lo = (lo + Math.imul(al6, bl9)) | 0;
    mid = (mid + Math.imul(al6, bh9)) | 0;
    mid = (mid + Math.imul(ah6, bl9)) | 0;
    hi = (hi + Math.imul(ah6, bh9)) | 0;
    var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
    w15 &= 0x3ffffff;
    /* k = 16 */
    lo = Math.imul(al9, bl7);
    mid = Math.imul(al9, bh7);
    mid = (mid + Math.imul(ah9, bl7)) | 0;
    hi = Math.imul(ah9, bh7);
    lo = (lo + Math.imul(al8, bl8)) | 0;
    mid = (mid + Math.imul(al8, bh8)) | 0;
    mid = (mid + Math.imul(ah8, bl8)) | 0;
    hi = (hi + Math.imul(ah8, bh8)) | 0;
    lo = (lo + Math.imul(al7, bl9)) | 0;
    mid = (mid + Math.imul(al7, bh9)) | 0;
    mid = (mid + Math.imul(ah7, bl9)) | 0;
    hi = (hi + Math.imul(ah7, bh9)) | 0;
    var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
    w16 &= 0x3ffffff;
    /* k = 17 */
    lo = Math.imul(al9, bl8);
    mid = Math.imul(al9, bh8);
    mid = (mid + Math.imul(ah9, bl8)) | 0;
    hi = Math.imul(ah9, bh8);
    lo = (lo + Math.imul(al8, bl9)) | 0;
    mid = (mid + Math.imul(al8, bh9)) | 0;
    mid = (mid + Math.imul(ah8, bl9)) | 0;
    hi = (hi + Math.imul(ah8, bh9)) | 0;
    var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
    w17 &= 0x3ffffff;
    /* k = 18 */
    lo = Math.imul(al9, bl9);
    mid = Math.imul(al9, bh9);
    mid = (mid + Math.imul(ah9, bl9)) | 0;
    hi = Math.imul(ah9, bh9);
    var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
    w18 &= 0x3ffffff;
    o[0] = w0;
    o[1] = w1;
    o[2] = w2;
    o[3] = w3;
    o[4] = w4;
    o[5] = w5;
    o[6] = w6;
    o[7] = w7;
    o[8] = w8;
    o[9] = w9;
    o[10] = w10;
    o[11] = w11;
    o[12] = w12;
    o[13] = w13;
    o[14] = w14;
    o[15] = w15;
    o[16] = w16;
    o[17] = w17;
    o[18] = w18;
    if (c !== 0) {
      o[19] = c;
      out.length++;
    }
    return out;
  };

  // Polyfill comb
  if (!Math.imul) {
    comb10MulTo = smallMulTo;
  }

  function bigMulTo (self, num, out) {
    out.negative = num.negative ^ self.negative;
    out.length = self.length + num.length;

    var carry = 0;
    var hncarry = 0;
    for (var k = 0; k < out.length - 1; k++) {
      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
      // note that ncarry could be >= 0x3ffffff
      var ncarry = hncarry;
      hncarry = 0;
      var rword = carry & 0x3ffffff;
      var maxJ = Math.min(k, num.length - 1);
      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
        var i = k - j;
        var a = self.words[i] | 0;
        var b = num.words[j] | 0;
        var r = a * b;

        var lo = r & 0x3ffffff;
        ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
        lo = (lo + rword) | 0;
        rword = lo & 0x3ffffff;
        ncarry = (ncarry + (lo >>> 26)) | 0;

        hncarry += ncarry >>> 26;
        ncarry &= 0x3ffffff;
      }
      out.words[k] = rword;
      carry = ncarry;
      ncarry = hncarry;
    }
    if (carry !== 0) {
      out.words[k] = carry;
    } else {
      out.length--;
    }

    return out.strip();
  }

  function jumboMulTo (self, num, out) {
    var fftm = new FFTM();
    return fftm.mulp(self, num, out);
  }

  BN.prototype.mulTo = function mulTo (num, out) {
    var res;
    var len = this.length + num.length;
    if (this.length === 10 && num.length === 10) {
      res = comb10MulTo(this, num, out);
    } else if (len < 63) {
      res = smallMulTo(this, num, out);
    } else if (len < 1024) {
      res = bigMulTo(this, num, out);
    } else {
      res = jumboMulTo(this, num, out);
    }

    return res;
  };

  // Cooley-Tukey algorithm for FFT
  // slightly revisited to rely on looping instead of recursion

  function FFTM (x, y) {
    this.x = x;
    this.y = y;
  }

  FFTM.prototype.makeRBT = function makeRBT (N) {
    var t = new Array(N);
    var l = BN.prototype._countBits(N) - 1;
    for (var i = 0; i < N; i++) {
      t[i] = this.revBin(i, l, N);
    }

    return t;
  };

  // Returns binary-reversed representation of `x`
  FFTM.prototype.revBin = function revBin (x, l, N) {
    if (x === 0 || x === N - 1) return x;

    var rb = 0;
    for (var i = 0; i < l; i++) {
      rb |= (x & 1) << (l - i - 1);
      x >>= 1;
    }

    return rb;
  };

  // Performs "tweedling" phase, therefore 'emulating'
  // behaviour of the recursive algorithm
  FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
    for (var i = 0; i < N; i++) {
      rtws[i] = rws[rbt[i]];
      itws[i] = iws[rbt[i]];
    }
  };

  FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
    this.permute(rbt, rws, iws, rtws, itws, N);

    for (var s = 1; s < N; s <<= 1) {
      var l = s << 1;

      var rtwdf = Math.cos(2 * Math.PI / l);
      var itwdf = Math.sin(2 * Math.PI / l);

      for (var p = 0; p < N; p += l) {
        var rtwdf_ = rtwdf;
        var itwdf_ = itwdf;

        for (var j = 0; j < s; j++) {
          var re = rtws[p + j];
          var ie = itws[p + j];

          var ro = rtws[p + j + s];
          var io = itws[p + j + s];

          var rx = rtwdf_ * ro - itwdf_ * io;

          io = rtwdf_ * io + itwdf_ * ro;
          ro = rx;

          rtws[p + j] = re + ro;
          itws[p + j] = ie + io;

          rtws[p + j + s] = re - ro;
          itws[p + j + s] = ie - io;

          /* jshint maxdepth : false */
          if (j !== l) {
            rx = rtwdf * rtwdf_ - itwdf * itwdf_;

            itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
            rtwdf_ = rx;
          }
        }
      }
    }
  };

  FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
    var N = Math.max(m, n) | 1;
    var odd = N & 1;
    var i = 0;
    for (N = N / 2 | 0; N; N = N >>> 1) {
      i++;
    }

    return 1 << i + 1 + odd;
  };

  FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
    if (N <= 1) return;

    for (var i = 0; i < N / 2; i++) {
      var t = rws[i];

      rws[i] = rws[N - i - 1];
      rws[N - i - 1] = t;

      t = iws[i];

      iws[i] = -iws[N - i - 1];
      iws[N - i - 1] = -t;
    }
  };

  FFTM.prototype.normalize13b = function normalize13b (ws, N) {
    var carry = 0;
    for (var i = 0; i < N / 2; i++) {
      var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
        Math.round(ws[2 * i] / N) +
        carry;

      ws[i] = w & 0x3ffffff;

      if (w < 0x4000000) {
        carry = 0;
      } else {
        carry = w / 0x4000000 | 0;
      }
    }

    return ws;
  };

  FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
    var carry = 0;
    for (var i = 0; i < len; i++) {
      carry = carry + (ws[i] | 0);

      rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
      rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
    }

    // Pad with zeroes
    for (i = 2 * len; i < N; ++i) {
      rws[i] = 0;
    }

    assert(carry === 0);
    assert((carry & ~0x1fff) === 0);
  };

  FFTM.prototype.stub = function stub (N) {
    var ph = new Array(N);
    for (var i = 0; i < N; i++) {
      ph[i] = 0;
    }

    return ph;
  };

  FFTM.prototype.mulp = function mulp (x, y, out) {
    var N = 2 * this.guessLen13b(x.length, y.length);

    var rbt = this.makeRBT(N);

    var _ = this.stub(N);

    var rws = new Array(N);
    var rwst = new Array(N);
    var iwst = new Array(N);

    var nrws = new Array(N);
    var nrwst = new Array(N);
    var niwst = new Array(N);

    var rmws = out.words;
    rmws.length = N;

    this.convert13b(x.words, x.length, rws, N);
    this.convert13b(y.words, y.length, nrws, N);

    this.transform(rws, _, rwst, iwst, N, rbt);
    this.transform(nrws, _, nrwst, niwst, N, rbt);

    for (var i = 0; i < N; i++) {
      var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
      iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
      rwst[i] = rx;
    }

    this.conjugate(rwst, iwst, N);
    this.transform(rwst, iwst, rmws, _, N, rbt);
    this.conjugate(rmws, _, N);
    this.normalize13b(rmws, N);

    out.negative = x.negative ^ y.negative;
    out.length = x.length + y.length;
    return out.strip();
  };

  // Multiply `this` by `num`
  BN.prototype.mul = function mul (num) {
    var out = new BN(null);
    out.words = new Array(this.length + num.length);
    return this.mulTo(num, out);
  };

  // Multiply employing FFT
  BN.prototype.mulf = function mulf (num) {
    var out = new BN(null);
    out.words = new Array(this.length + num.length);
    return jumboMulTo(this, num, out);
  };

  // In-place Multiplication
  BN.prototype.imul = function imul (num) {
    return this.clone().mulTo(num, this);
  };

  BN.prototype.imuln = function imuln (num) {
    assert(typeof num === 'number');
    assert(num < 0x4000000);

    // Carry
    var carry = 0;
    for (var i = 0; i < this.length; i++) {
      var w = (this.words[i] | 0) * num;
      var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
      carry >>= 26;
      carry += (w / 0x4000000) | 0;
      // NOTE: lo is 27bit maximum
      carry += lo >>> 26;
      this.words[i] = lo & 0x3ffffff;
    }

    if (carry !== 0) {
      this.words[i] = carry;
      this.length++;
    }

    return this;
  };

  BN.prototype.muln = function muln (num) {
    return this.clone().imuln(num);
  };

  // `this` * `this`
  BN.prototype.sqr = function sqr () {
    return this.mul(this);
  };

  // `this` * `this` in-place
  BN.prototype.isqr = function isqr () {
    return this.imul(this.clone());
  };

  // Math.pow(`this`, `num`)
  BN.prototype.pow = function pow (num) {
    var w = toBitArray(num);
    if (w.length === 0) return new BN(1);

    // Skip leading zeroes
    var res = this;
    for (var i = 0; i < w.length; i++, res = res.sqr()) {
      if (w[i] !== 0) break;
    }

    if (++i < w.length) {
      for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
        if (w[i] === 0) continue;

        res = res.mul(q);
      }
    }

    return res;
  };

  // Shift-left in-place
  BN.prototype.iushln = function iushln (bits) {
    assert(typeof bits === 'number' && bits >= 0);
    var r = bits % 26;
    var s = (bits - r) / 26;
    var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
    var i;

    if (r !== 0) {
      var carry = 0;

      for (i = 0; i < this.length; i++) {
        var newCarry = this.words[i] & carryMask;
        var c = ((this.words[i] | 0) - newCarry) << r;
        this.words[i] = c | carry;
        carry = newCarry >>> (26 - r);
      }

      if (carry) {
        this.words[i] = carry;
        this.length++;
      }
    }

    if (s !== 0) {
      for (i = this.length - 1; i >= 0; i--) {
        this.words[i + s] = this.words[i];
      }

      for (i = 0; i < s; i++) {
        this.words[i] = 0;
      }

      this.length += s;
    }

    return this.strip();
  };

  BN.prototype.ishln = function ishln (bits) {
    // TODO(indutny): implement me
    assert(this.negative === 0);
    return this.iushln(bits);
  };

  // Shift-right in-place
  // NOTE: `hint` is a lowest bit before trailing zeroes
  // NOTE: if `extended` is present - it will be filled with destroyed bits
  BN.prototype.iushrn = function iushrn (bits, hint, extended) {
    assert(typeof bits === 'number' && bits >= 0);
    var h;
    if (hint) {
      h = (hint - (hint % 26)) / 26;
    } else {
      h = 0;
    }

    var r = bits % 26;
    var s = Math.min((bits - r) / 26, this.length);
    var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
    var maskedWords = extended;

    h -= s;
    h = Math.max(0, h);

    // Extended mode, copy masked part
    if (maskedWords) {
      for (var i = 0; i < s; i++) {
        maskedWords.words[i] = this.words[i];
      }
      maskedWords.length = s;
    }

    if (s === 0) ; else if (this.length > s) {
      this.length -= s;
      for (i = 0; i < this.length; i++) {
        this.words[i] = this.words[i + s];
      }
    } else {
      this.words[0] = 0;
      this.length = 1;
    }

    var carry = 0;
    for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
      var word = this.words[i] | 0;
      this.words[i] = (carry << (26 - r)) | (word >>> r);
      carry = word & mask;
    }

    // Push carried bits as a mask
    if (maskedWords && carry !== 0) {
      maskedWords.words[maskedWords.length++] = carry;
    }

    if (this.length === 0) {
      this.words[0] = 0;
      this.length = 1;
    }

    return this.strip();
  };

  BN.prototype.ishrn = function ishrn (bits, hint, extended) {
    // TODO(indutny): implement me
    assert(this.negative === 0);
    return this.iushrn(bits, hint, extended);
  };

  // Shift-left
  BN.prototype.shln = function shln (bits) {
    return this.clone().ishln(bits);
  };

  BN.prototype.ushln = function ushln (bits) {
    return this.clone().iushln(bits);
  };

  // Shift-right
  BN.prototype.shrn = function shrn (bits) {
    return this.clone().ishrn(bits);
  };

  BN.prototype.ushrn = function ushrn (bits) {
    return this.clone().iushrn(bits);
  };

  // Test if n bit is set
  BN.prototype.testn = function testn (bit) {
    assert(typeof bit === 'number' && bit >= 0);
    var r = bit % 26;
    var s = (bit - r) / 26;
    var q = 1 << r;

    // Fast case: bit is much higher than all existing words
    if (this.length <= s) return false;

    // Check bit and return
    var w = this.words[s];

    return !!(w & q);
  };

  // Return only lowers bits of number (in-place)
  BN.prototype.imaskn = function imaskn (bits) {
    assert(typeof bits === 'number' && bits >= 0);
    var r = bits % 26;
    var s = (bits - r) / 26;

    assert(this.negative === 0, 'imaskn works only with positive numbers');

    if (this.length <= s) {
      return this;
    }

    if (r !== 0) {
      s++;
    }
    this.length = Math.min(s, this.length);

    if (r !== 0) {
      var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
      this.words[this.length - 1] &= mask;
    }

    return this.strip();
  };

  // Return only lowers bits of number
  BN.prototype.maskn = function maskn (bits) {
    return this.clone().imaskn(bits);
  };

  // Add plain number `num` to `this`
  BN.prototype.iaddn = function iaddn (num) {
    assert(typeof num === 'number');
    assert(num < 0x4000000);
    if (num < 0) return this.isubn(-num);

    // Possible sign change
    if (this.negative !== 0) {
      if (this.length === 1 && (this.words[0] | 0) < num) {
        this.words[0] = num - (this.words[0] | 0);
        this.negative = 0;
        return this;
      }

      this.negative = 0;
      this.isubn(num);
      this.negative = 1;
      return this;
    }

    // Add without checks
    return this._iaddn(num);
  };

  BN.prototype._iaddn = function _iaddn (num) {
    this.words[0] += num;

    // Carry
    for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
      this.words[i] -= 0x4000000;
      if (i === this.length - 1) {
        this.words[i + 1] = 1;
      } else {
        this.words[i + 1]++;
      }
    }
    this.length = Math.max(this.length, i + 1);

    return this;
  };

  // Subtract plain number `num` from `this`
  BN.prototype.isubn = function isubn (num) {
    assert(typeof num === 'number');
    assert(num < 0x4000000);
    if (num < 0) return this.iaddn(-num);

    if (this.negative !== 0) {
      this.negative = 0;
      this.iaddn(num);
      this.negative = 1;
      return this;
    }

    this.words[0] -= num;

    if (this.length === 1 && this.words[0] < 0) {
      this.words[0] = -this.words[0];
      this.negative = 1;
    } else {
      // Carry
      for (var i = 0; i < this.length && this.words[i] < 0; i++) {
        this.words[i] += 0x4000000;
        this.words[i + 1] -= 1;
      }
    }

    return this.strip();
  };

  BN.prototype.addn = function addn (num) {
    return this.clone().iaddn(num);
  };

  BN.prototype.subn = function subn (num) {
    return this.clone().isubn(num);
  };

  BN.prototype.iabs = function iabs () {
    this.negative = 0;

    return this;
  };

  BN.prototype.abs = function abs () {
    return this.clone().iabs();
  };

  BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
    var len = num.length + shift;
    var i;

    this._expand(len);

    var w;
    var carry = 0;
    for (i = 0; i < num.length; i++) {
      w = (this.words[i + shift] | 0) + carry;
      var right = (num.words[i] | 0) * mul;
      w -= right & 0x3ffffff;
      carry = (w >> 26) - ((right / 0x4000000) | 0);
      this.words[i + shift] = w & 0x3ffffff;
    }
    for (; i < this.length - shift; i++) {
      w = (this.words[i + shift] | 0) + carry;
      carry = w >> 26;
      this.words[i + shift] = w & 0x3ffffff;
    }

    if (carry === 0) return this.strip();

    // Subtraction overflow
    assert(carry === -1);
    carry = 0;
    for (i = 0; i < this.length; i++) {
      w = -(this.words[i] | 0) + carry;
      carry = w >> 26;
      this.words[i] = w & 0x3ffffff;
    }
    this.negative = 1;

    return this.strip();
  };

  BN.prototype._wordDiv = function _wordDiv (num, mode) {
    var shift = this.length - num.length;

    var a = this.clone();
    var b = num;

    // Normalize
    var bhi = b.words[b.length - 1] | 0;
    var bhiBits = this._countBits(bhi);
    shift = 26 - bhiBits;
    if (shift !== 0) {
      b = b.ushln(shift);
      a.iushln(shift);
      bhi = b.words[b.length - 1] | 0;
    }

    // Initialize quotient
    var m = a.length - b.length;
    var q;

    if (mode !== 'mod') {
      q = new BN(null);
      q.length = m + 1;
      q.words = new Array(q.length);
      for (var i = 0; i < q.length; i++) {
        q.words[i] = 0;
      }
    }

    var diff = a.clone()._ishlnsubmul(b, 1, m);
    if (diff.negative === 0) {
      a = diff;
      if (q) {
        q.words[m] = 1;
      }
    }

    for (var j = m - 1; j >= 0; j--) {
      var qj = (a.words[b.length + j] | 0) * 0x4000000 +
        (a.words[b.length + j - 1] | 0);

      // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
      // (0x7ffffff)
      qj = Math.min((qj / bhi) | 0, 0x3ffffff);

      a._ishlnsubmul(b, qj, j);
      while (a.negative !== 0) {
        qj--;
        a.negative = 0;
        a._ishlnsubmul(b, 1, j);
        if (!a.isZero()) {
          a.negative ^= 1;
        }
      }
      if (q) {
        q.words[j] = qj;
      }
    }
    if (q) {
      q.strip();
    }
    a.strip();

    // Denormalize
    if (mode !== 'div' && shift !== 0) {
      a.iushrn(shift);
    }

    return {
      div: q || null,
      mod: a
    };
  };

  // NOTE: 1) `mode` can be set to `mod` to request mod only,
  //       to `div` to request div only, or be absent to
  //       request both div & mod
  //       2) `positive` is true if unsigned mod is requested
  BN.prototype.divmod = function divmod (num, mode, positive) {
    assert(!num.isZero());

    if (this.isZero()) {
      return {
        div: new BN(0),
        mod: new BN(0)
      };
    }

    var div, mod, res;
    if (this.negative !== 0 && num.negative === 0) {
      res = this.neg().divmod(num, mode);

      if (mode !== 'mod') {
        div = res.div.neg();
      }

      if (mode !== 'div') {
        mod = res.mod.neg();
        if (positive && mod.negative !== 0) {
          mod.iadd(num);
        }
      }

      return {
        div: div,
        mod: mod
      };
    }

    if (this.negative === 0 && num.negative !== 0) {
      res = this.divmod(num.neg(), mode);

      if (mode !== 'mod') {
        div = res.div.neg();
      }

      return {
        div: div,
        mod: res.mod
      };
    }

    if ((this.negative & num.negative) !== 0) {
      res = this.neg().divmod(num.neg(), mode);

      if (mode !== 'div') {
        mod = res.mod.neg();
        if (positive && mod.negative !== 0) {
          mod.isub(num);
        }
      }

      return {
        div: res.div,
        mod: mod
      };
    }

    // Both numbers are positive at this point

    // Strip both numbers to approximate shift value
    if (num.length > this.length || this.cmp(num) < 0) {
      return {
        div: new BN(0),
        mod: this
      };
    }

    // Very short reduction
    if (num.length === 1) {
      if (mode === 'div') {
        return {
          div: this.divn(num.words[0]),
          mod: null
        };
      }

      if (mode === 'mod') {
        return {
          div: null,
          mod: new BN(this.modn(num.words[0]))
        };
      }

      return {
        div: this.divn(num.words[0]),
        mod: new BN(this.modn(num.words[0]))
      };
    }

    return this._wordDiv(num, mode);
  };

  // Find `this` / `num`
  BN.prototype.div = function div (num) {
    return this.divmod(num, 'div', false).div;
  };

  // Find `this` % `num`
  BN.prototype.mod = function mod (num) {
    return this.divmod(num, 'mod', false).mod;
  };

  BN.prototype.umod = function umod (num) {
    return this.divmod(num, 'mod', true).mod;
  };

  // Find Round(`this` / `num`)
  BN.prototype.divRound = function divRound (num) {
    var dm = this.divmod(num);

    // Fast case - exact division
    if (dm.mod.isZero()) return dm.div;

    var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;

    var half = num.ushrn(1);
    var r2 = num.andln(1);
    var cmp = mod.cmp(half);

    // Round down
    if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;

    // Round up
    return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
  };

  BN.prototype.modn = function modn (num) {
    assert(num <= 0x3ffffff);
    var p = (1 << 26) % num;

    var acc = 0;
    for (var i = this.length - 1; i >= 0; i--) {
      acc = (p * acc + (this.words[i] | 0)) % num;
    }

    return acc;
  };

  // In-place division by number
  BN.prototype.idivn = function idivn (num) {
    assert(num <= 0x3ffffff);

    var carry = 0;
    for (var i = this.length - 1; i >= 0; i--) {
      var w = (this.words[i] | 0) + carry * 0x4000000;
      this.words[i] = (w / num) | 0;
      carry = w % num;
    }

    return this.strip();
  };

  BN.prototype.divn = function divn (num) {
    return this.clone().idivn(num);
  };

  BN.prototype.egcd = function egcd (p) {
    assert(p.negative === 0);
    assert(!p.isZero());

    var x = this;
    var y = p.clone();

    if (x.negative !== 0) {
      x = x.umod(p);
    } else {
      x = x.clone();
    }

    // A * x + B * y = x
    var A = new BN(1);
    var B = new BN(0);

    // C * x + D * y = y
    var C = new BN(0);
    var D = new BN(1);

    var g = 0;

    while (x.isEven() && y.isEven()) {
      x.iushrn(1);
      y.iushrn(1);
      ++g;
    }

    var yp = y.clone();
    var xp = x.clone();

    while (!x.isZero()) {
      for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
      if (i > 0) {
        x.iushrn(i);
        while (i-- > 0) {
          if (A.isOdd() || B.isOdd()) {
            A.iadd(yp);
            B.isub(xp);
          }

          A.iushrn(1);
          B.iushrn(1);
        }
      }

      for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
      if (j > 0) {
        y.iushrn(j);
        while (j-- > 0) {
          if (C.isOdd() || D.isOdd()) {
            C.iadd(yp);
            D.isub(xp);
          }

          C.iushrn(1);
          D.iushrn(1);
        }
      }

      if (x.cmp(y) >= 0) {
        x.isub(y);
        A.isub(C);
        B.isub(D);
      } else {
        y.isub(x);
        C.isub(A);
        D.isub(B);
      }
    }

    return {
      a: C,
      b: D,
      gcd: y.iushln(g)
    };
  };

  // This is reduced incarnation of the binary EEA
  // above, designated to invert members of the
  // _prime_ fields F(p) at a maximal speed
  BN.prototype._invmp = function _invmp (p) {
    assert(p.negative === 0);
    assert(!p.isZero());

    var a = this;
    var b = p.clone();

    if (a.negative !== 0) {
      a = a.umod(p);
    } else {
      a = a.clone();
    }

    var x1 = new BN(1);
    var x2 = new BN(0);

    var delta = b.clone();

    while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
      for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
      if (i > 0) {
        a.iushrn(i);
        while (i-- > 0) {
          if (x1.isOdd()) {
            x1.iadd(delta);
          }

          x1.iushrn(1);
        }
      }

      for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
      if (j > 0) {
        b.iushrn(j);
        while (j-- > 0) {
          if (x2.isOdd()) {
            x2.iadd(delta);
          }

          x2.iushrn(1);
        }
      }

      if (a.cmp(b) >= 0) {
        a.isub(b);
        x1.isub(x2);
      } else {
        b.isub(a);
        x2.isub(x1);
      }
    }

    var res;
    if (a.cmpn(1) === 0) {
      res = x1;
    } else {
      res = x2;
    }

    if (res.cmpn(0) < 0) {
      res.iadd(p);
    }

    return res;
  };

  BN.prototype.gcd = function gcd (num) {
    if (this.isZero()) return num.abs();
    if (num.isZero()) return this.abs();

    var a = this.clone();
    var b = num.clone();
    a.negative = 0;
    b.negative = 0;

    // Remove common factor of two
    for (var shift = 0; a.isEven() && b.isEven(); shift++) {
      a.iushrn(1);
      b.iushrn(1);
    }

    do {
      while (a.isEven()) {
        a.iushrn(1);
      }
      while (b.isEven()) {
        b.iushrn(1);
      }

      var r = a.cmp(b);
      if (r < 0) {
        // Swap `a` and `b` to make `a` always bigger than `b`
        var t = a;
        a = b;
        b = t;
      } else if (r === 0 || b.cmpn(1) === 0) {
        break;
      }

      a.isub(b);
    } while (true);

    return b.iushln(shift);
  };

  // Invert number in the field F(num)
  BN.prototype.invm = function invm (num) {
    return this.egcd(num).a.umod(num);
  };

  BN.prototype.isEven = function isEven () {
    return (this.words[0] & 1) === 0;
  };

  BN.prototype.isOdd = function isOdd () {
    return (this.words[0] & 1) === 1;
  };

  // And first word and num
  BN.prototype.andln = function andln (num) {
    return this.words[0] & num;
  };

  // Increment at the bit position in-line
  BN.prototype.bincn = function bincn (bit) {
    assert(typeof bit === 'number');
    var r = bit % 26;
    var s = (bit - r) / 26;
    var q = 1 << r;

    // Fast case: bit is much higher than all existing words
    if (this.length <= s) {
      this._expand(s + 1);
      this.words[s] |= q;
      return this;
    }

    // Add bit and propagate, if needed
    var carry = q;
    for (var i = s; carry !== 0 && i < this.length; i++) {
      var w = this.words[i] | 0;
      w += carry;
      carry = w >>> 26;
      w &= 0x3ffffff;
      this.words[i] = w;
    }
    if (carry !== 0) {
      this.words[i] = carry;
      this.length++;
    }
    return this;
  };

  BN.prototype.isZero = function isZero () {
    return this.length === 1 && this.words[0] === 0;
  };

  BN.prototype.cmpn = function cmpn (num) {
    var negative = num < 0;

    if (this.negative !== 0 && !negative) return -1;
    if (this.negative === 0 && negative) return 1;

    this.strip();

    var res;
    if (this.length > 1) {
      res = 1;
    } else {
      if (negative) {
        num = -num;
      }

      assert(num <= 0x3ffffff, 'Number is too big');

      var w = this.words[0] | 0;
      res = w === num ? 0 : w < num ? -1 : 1;
    }
    if (this.negative !== 0) return -res | 0;
    return res;
  };

  // Compare two numbers and return:
  // 1 - if `this` > `num`
  // 0 - if `this` == `num`
  // -1 - if `this` < `num`
  BN.prototype.cmp = function cmp (num) {
    if (this.negative !== 0 && num.negative === 0) return -1;
    if (this.negative === 0 && num.negative !== 0) return 1;

    var res = this.ucmp(num);
    if (this.negative !== 0) return -res | 0;
    return res;
  };

  // Unsigned comparison
  BN.prototype.ucmp = function ucmp (num) {
    // At this point both numbers have the same sign
    if (this.length > num.length) return 1;
    if (this.length < num.length) return -1;

    var res = 0;
    for (var i = this.length - 1; i >= 0; i--) {
      var a = this.words[i] | 0;
      var b = num.words[i] | 0;

      if (a === b) continue;
      if (a < b) {
        res = -1;
      } else if (a > b) {
        res = 1;
      }
      break;
    }
    return res;
  };

  BN.prototype.gtn = function gtn (num) {
    return this.cmpn(num) === 1;
  };

  BN.prototype.gt = function gt (num) {
    return this.cmp(num) === 1;
  };

  BN.prototype.gten = function gten (num) {
    return this.cmpn(num) >= 0;
  };

  BN.prototype.gte = function gte (num) {
    return this.cmp(num) >= 0;
  };

  BN.prototype.ltn = function ltn (num) {
    return this.cmpn(num) === -1;
  };

  BN.prototype.lt = function lt (num) {
    return this.cmp(num) === -1;
  };

  BN.prototype.lten = function lten (num) {
    return this.cmpn(num) <= 0;
  };

  BN.prototype.lte = function lte (num) {
    return this.cmp(num) <= 0;
  };

  BN.prototype.eqn = function eqn (num) {
    return this.cmpn(num) === 0;
  };

  BN.prototype.eq = function eq (num) {
    return this.cmp(num) === 0;
  };

  //
  // A reduce context, could be using montgomery or something better, depending
  // on the `m` itself.
  //
  BN.red = function red (num) {
    return new Red(num);
  };

  BN.prototype.toRed = function toRed (ctx) {
    assert(!this.red, 'Already a number in reduction context');
    assert(this.negative === 0, 'red works only with positives');
    return ctx.convertTo(this)._forceRed(ctx);
  };

  BN.prototype.fromRed = function fromRed () {
    assert(this.red, 'fromRed works only with numbers in reduction context');
    return this.red.convertFrom(this);
  };

  BN.prototype._forceRed = function _forceRed (ctx) {
    this.red = ctx;
    return this;
  };

  BN.prototype.forceRed = function forceRed (ctx) {
    assert(!this.red, 'Already a number in reduction context');
    return this._forceRed(ctx);
  };

  BN.prototype.redAdd = function redAdd (num) {
    assert(this.red, 'redAdd works only with red numbers');
    return this.red.add(this, num);
  };

  BN.prototype.redIAdd = function redIAdd (num) {
    assert(this.red, 'redIAdd works only with red numbers');
    return this.red.iadd(this, num);
  };

  BN.prototype.redSub = function redSub (num) {
    assert(this.red, 'redSub works only with red numbers');
    return this.red.sub(this, num);
  };

  BN.prototype.redISub = function redISub (num) {
    assert(this.red, 'redISub works only with red numbers');
    return this.red.isub(this, num);
  };

  BN.prototype.redShl = function redShl (num) {
    assert(this.red, 'redShl works only with red numbers');
    return this.red.shl(this, num);
  };

  BN.prototype.redMul = function redMul (num) {
    assert(this.red, 'redMul works only with red numbers');
    this.red._verify2(this, num);
    return this.red.mul(this, num);
  };

  BN.prototype.redIMul = function redIMul (num) {
    assert(this.red, 'redMul works only with red numbers');
    this.red._verify2(this, num);
    return this.red.imul(this, num);
  };

  BN.prototype.redSqr = function redSqr () {
    assert(this.red, 'redSqr works only with red numbers');
    this.red._verify1(this);
    return this.red.sqr(this);
  };

  BN.prototype.redISqr = function redISqr () {
    assert(this.red, 'redISqr works only with red numbers');
    this.red._verify1(this);
    return this.red.isqr(this);
  };

  // Square root over p
  BN.prototype.redSqrt = function redSqrt () {
    assert(this.red, 'redSqrt works only with red numbers');
    this.red._verify1(this);
    return this.red.sqrt(this);
  };

  BN.prototype.redInvm = function redInvm () {
    assert(this.red, 'redInvm works only with red numbers');
    this.red._verify1(this);
    return this.red.invm(this);
  };

  // Return negative clone of `this` % `red modulo`
  BN.prototype.redNeg = function redNeg () {
    assert(this.red, 'redNeg works only with red numbers');
    this.red._verify1(this);
    return this.red.neg(this);
  };

  BN.prototype.redPow = function redPow (num) {
    assert(this.red && !num.red, 'redPow(normalNum)');
    this.red._verify1(this);
    return this.red.pow(this, num);
  };

  // Prime numbers with efficient reduction
  var primes = {
    k256: null,
    p224: null,
    p192: null,
    p25519: null
  };

  // Pseudo-Mersenne prime
  function MPrime (name, p) {
    // P = 2 ^ N - K
    this.name = name;
    this.p = new BN(p, 16);
    this.n = this.p.bitLength();
    this.k = new BN(1).iushln(this.n).isub(this.p);

    this.tmp = this._tmp();
  }

  MPrime.prototype._tmp = function _tmp () {
    var tmp = new BN(null);
    tmp.words = new Array(Math.ceil(this.n / 13));
    return tmp;
  };

  MPrime.prototype.ireduce = function ireduce (num) {
    // Assumes that `num` is less than `P^2`
    // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
    var r = num;
    var rlen;

    do {
      this.split(r, this.tmp);
      r = this.imulK(r);
      r = r.iadd(this.tmp);
      rlen = r.bitLength();
    } while (rlen > this.n);

    var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
    if (cmp === 0) {
      r.words[0] = 0;
      r.length = 1;
    } else if (cmp > 0) {
      r.isub(this.p);
    } else {
      r.strip();
    }

    return r;
  };

  MPrime.prototype.split = function split (input, out) {
    input.iushrn(this.n, 0, out);
  };

  MPrime.prototype.imulK = function imulK (num) {
    return num.imul(this.k);
  };

  function K256 () {
    MPrime.call(
      this,
      'k256',
      'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
  }
  inherits(K256, MPrime);

  K256.prototype.split = function split (input, output) {
    // 256 = 9 * 26 + 22
    var mask = 0x3fffff;

    var outLen = Math.min(input.length, 9);
    for (var i = 0; i < outLen; i++) {
      output.words[i] = input.words[i];
    }
    output.length = outLen;

    if (input.length <= 9) {
      input.words[0] = 0;
      input.length = 1;
      return;
    }

    // Shift by 9 limbs
    var prev = input.words[9];
    output.words[output.length++] = prev & mask;

    for (i = 10; i < input.length; i++) {
      var next = input.words[i] | 0;
      input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
      prev = next;
    }
    prev >>>= 22;
    input.words[i - 10] = prev;
    if (prev === 0 && input.length > 10) {
      input.length -= 10;
    } else {
      input.length -= 9;
    }
  };

  K256.prototype.imulK = function imulK (num) {
    // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
    num.words[num.length] = 0;
    num.words[num.length + 1] = 0;
    num.length += 2;

    // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
    var lo = 0;
    for (var i = 0; i < num.length; i++) {
      var w = num.words[i] | 0;
      lo += w * 0x3d1;
      num.words[i] = lo & 0x3ffffff;
      lo = w * 0x40 + ((lo / 0x4000000) | 0);
    }

    // Fast length reduction
    if (num.words[num.length - 1] === 0) {
      num.length--;
      if (num.words[num.length - 1] === 0) {
        num.length--;
      }
    }
    return num;
  };

  function P224 () {
    MPrime.call(
      this,
      'p224',
      'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
  }
  inherits(P224, MPrime);

  function P192 () {
    MPrime.call(
      this,
      'p192',
      'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
  }
  inherits(P192, MPrime);

  function P25519 () {
    // 2 ^ 255 - 19
    MPrime.call(
      this,
      '25519',
      '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
  }
  inherits(P25519, MPrime);

  P25519.prototype.imulK = function imulK (num) {
    // K = 0x13
    var carry = 0;
    for (var i = 0; i < num.length; i++) {
      var hi = (num.words[i] | 0) * 0x13 + carry;
      var lo = hi & 0x3ffffff;
      hi >>>= 26;

      num.words[i] = lo;
      carry = hi;
    }
    if (carry !== 0) {
      num.words[num.length++] = carry;
    }
    return num;
  };

  // Exported mostly for testing purposes, use plain name instead
  BN._prime = function prime (name) {
    // Cached version of prime
    if (primes[name]) return primes[name];

    var prime;
    if (name === 'k256') {
      prime = new K256();
    } else if (name === 'p224') {
      prime = new P224();
    } else if (name === 'p192') {
      prime = new P192();
    } else if (name === 'p25519') {
      prime = new P25519();
    } else {
      throw new Error('Unknown prime ' + name);
    }
    primes[name] = prime;

    return prime;
  };

  //
  // Base reduction engine
  //
  function Red (m) {
    if (typeof m === 'string') {
      var prime = BN._prime(m);
      this.m = prime.p;
      this.prime = prime;
    } else {
      assert(m.gtn(1), 'modulus must be greater than 1');
      this.m = m;
      this.prime = null;
    }
  }

  Red.prototype._verify1 = function _verify1 (a) {
    assert(a.negative === 0, 'red works only with positives');
    assert(a.red, 'red works only with red numbers');
  };

  Red.prototype._verify2 = function _verify2 (a, b) {
    assert((a.negative | b.negative) === 0, 'red works only with positives');
    assert(a.red && a.red === b.red,
      'red works only with red numbers');
  };

  Red.prototype.imod = function imod (a) {
    if (this.prime) return this.prime.ireduce(a)._forceRed(this);
    return a.umod(this.m)._forceRed(this);
  };

  Red.prototype.neg = function neg (a) {
    if (a.isZero()) {
      return a.clone();
    }

    return this.m.sub(a)._forceRed(this);
  };

  Red.prototype.add = function add (a, b) {
    this._verify2(a, b);

    var res = a.add(b);
    if (res.cmp(this.m) >= 0) {
      res.isub(this.m);
    }
    return res._forceRed(this);
  };

  Red.prototype.iadd = function iadd (a, b) {
    this._verify2(a, b);

    var res = a.iadd(b);
    if (res.cmp(this.m) >= 0) {
      res.isub(this.m);
    }
    return res;
  };

  Red.prototype.sub = function sub (a, b) {
    this._verify2(a, b);

    var res = a.sub(b);
    if (res.cmpn(0) < 0) {
      res.iadd(this.m);
    }
    return res._forceRed(this);
  };

  Red.prototype.isub = function isub (a, b) {
    this._verify2(a, b);

    var res = a.isub(b);
    if (res.cmpn(0) < 0) {
      res.iadd(this.m);
    }
    return res;
  };

  Red.prototype.shl = function shl (a, num) {
    this._verify1(a);
    return this.imod(a.ushln(num));
  };

  Red.prototype.imul = function imul (a, b) {
    this._verify2(a, b);
    return this.imod(a.imul(b));
  };

  Red.prototype.mul = function mul (a, b) {
    this._verify2(a, b);
    return this.imod(a.mul(b));
  };

  Red.prototype.isqr = function isqr (a) {
    return this.imul(a, a.clone());
  };

  Red.prototype.sqr = function sqr (a) {
    return this.mul(a, a);
  };

  Red.prototype.sqrt = function sqrt (a) {
    if (a.isZero()) return a.clone();

    var mod3 = this.m.andln(3);
    assert(mod3 % 2 === 1);

    // Fast case
    if (mod3 === 3) {
      var pow = this.m.add(new BN(1)).iushrn(2);
      return this.pow(a, pow);
    }

    // Tonelli-Shanks algorithm (Totally unoptimized and slow)
    //
    // Find Q and S, that Q * 2 ^ S = (P - 1)
    var q = this.m.subn(1);
    var s = 0;
    while (!q.isZero() && q.andln(1) === 0) {
      s++;
      q.iushrn(1);
    }
    assert(!q.isZero());

    var one = new BN(1).toRed(this);
    var nOne = one.redNeg();

    // Find quadratic non-residue
    // NOTE: Max is such because of generalized Riemann hypothesis.
    var lpow = this.m.subn(1).iushrn(1);
    var z = this.m.bitLength();
    z = new BN(2 * z * z).toRed(this);

    while (this.pow(z, lpow).cmp(nOne) !== 0) {
      z.redIAdd(nOne);
    }

    var c = this.pow(z, q);
    var r = this.pow(a, q.addn(1).iushrn(1));
    var t = this.pow(a, q);
    var m = s;
    while (t.cmp(one) !== 0) {
      var tmp = t;
      for (var i = 0; tmp.cmp(one) !== 0; i++) {
        tmp = tmp.redSqr();
      }
      assert(i < m);
      var b = this.pow(c, new BN(1).iushln(m - i - 1));

      r = r.redMul(b);
      c = b.redSqr();
      t = t.redMul(c);
      m = i;
    }

    return r;
  };

  Red.prototype.invm = function invm (a) {
    var inv = a._invmp(this.m);
    if (inv.negative !== 0) {
      inv.negative = 0;
      return this.imod(inv).redNeg();
    } else {
      return this.imod(inv);
    }
  };

  Red.prototype.pow = function pow (a, num) {
    if (num.isZero()) return new BN(1).toRed(this);
    if (num.cmpn(1) === 0) return a.clone();

    var windowSize = 4;
    var wnd = new Array(1 << windowSize);
    wnd[0] = new BN(1).toRed(this);
    wnd[1] = a;
    for (var i = 2; i < wnd.length; i++) {
      wnd[i] = this.mul(wnd[i - 1], a);
    }

    var res = wnd[0];
    var current = 0;
    var currentLen = 0;
    var start = num.bitLength() % 26;
    if (start === 0) {
      start = 26;
    }

    for (i = num.length - 1; i >= 0; i--) {
      var word = num.words[i];
      for (var j = start - 1; j >= 0; j--) {
        var bit = (word >> j) & 1;
        if (res !== wnd[0]) {
          res = this.sqr(res);
        }

        if (bit === 0 && current === 0) {
          currentLen = 0;
          continue;
        }

        current <<= 1;
        current |= bit;
        currentLen++;
        if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;

        res = this.mul(res, wnd[current]);
        currentLen = 0;
        current = 0;
      }
      start = 26;
    }

    return res;
  };

  Red.prototype.convertTo = function convertTo (num) {
    var r = num.umod(this.m);

    return r === num ? r.clone() : r;
  };

  Red.prototype.convertFrom = function convertFrom (num) {
    var res = num.clone();
    res.red = null;
    return res;
  };

  //
  // Montgomery method engine
  //

  BN.mont = function mont (num) {
    return new Mont(num);
  };

  function Mont (m) {
    Red.call(this, m);

    this.shift = this.m.bitLength();
    if (this.shift % 26 !== 0) {
      this.shift += 26 - (this.shift % 26);
    }

    this.r = new BN(1).iushln(this.shift);
    this.r2 = this.imod(this.r.sqr());
    this.rinv = this.r._invmp(this.m);

    this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
    this.minv = this.minv.umod(this.r);
    this.minv = this.r.sub(this.minv);
  }
  inherits(Mont, Red);

  Mont.prototype.convertTo = function convertTo (num) {
    return this.imod(num.ushln(this.shift));
  };

  Mont.prototype.convertFrom = function convertFrom (num) {
    var r = this.imod(num.mul(this.rinv));
    r.red = null;
    return r;
  };

  Mont.prototype.imul = function imul (a, b) {
    if (a.isZero() || b.isZero()) {
      a.words[0] = 0;
      a.length = 1;
      return a;
    }

    var t = a.imul(b);
    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
    var u = t.isub(c).iushrn(this.shift);
    var res = u;

    if (u.cmp(this.m) >= 0) {
      res = u.isub(this.m);
    } else if (u.cmpn(0) < 0) {
      res = u.iadd(this.m);
    }

    return res._forceRed(this);
  };

  Mont.prototype.mul = function mul (a, b) {
    if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);

    var t = a.mul(b);
    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
    var u = t.isub(c).iushrn(this.shift);
    var res = u;
    if (u.cmp(this.m) >= 0) {
      res = u.isub(this.m);
    } else if (u.cmpn(0) < 0) {
      res = u.iadd(this.m);
    }

    return res._forceRed(this);
  };

  Mont.prototype.invm = function invm (a) {
    // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
    var res = this.imod(a._invmp(this.m).mul(this.r2));
    return res._forceRed(this);
  };
})(module, commonjsGlobal);
});

var bn$1 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  'default': bn,
  __moduleExports: bn
});

/**
 * @fileoverview
 * BigInteger implementation of basic operations
 * Wrapper of bn.js library (wwww.github.com/indutny/bn.js)
 * @module biginteger/bn
 * @private
 */

/**
 * @private
 */
class BigInteger$1 {
  /**
   * Get a BigInteger (input must be big endian for strings and arrays)
   * @param {Number|String|Uint8Array} n - Value to convert
   * @throws {Error} on undefined input
   */
  constructor(n) {
    if (n === undefined) {
      throw new Error('Invalid BigInteger input');
    }

    this.value = new bn(n);
  }

  clone() {
    const clone = new BigInteger$1(null);
    this.value.copy(clone.value);
    return clone;
  }

  /**
   * BigInteger increment in place
   */
  iinc() {
    this.value.iadd(new bn(1));
    return this;
  }

  /**
   * BigInteger increment
   * @returns {BigInteger} this + 1.
   */
  inc() {
    return this.clone().iinc();
  }

  /**
   * BigInteger decrement in place
   */
  idec() {
    this.value.isub(new bn(1));
    return this;
  }

  /**
   * BigInteger decrement
   * @returns {BigInteger} this - 1.
   */
  dec() {
    return this.clone().idec();
  }


  /**
   * BigInteger addition in place
   * @param {BigInteger} x - Value to add
   */
  iadd(x) {
    this.value.iadd(x.value);
    return this;
  }

  /**
   * BigInteger addition
   * @param {BigInteger} x - Value to add
   * @returns {BigInteger} this + x.
   */
  add(x) {
    return this.clone().iadd(x);
  }

  /**
   * BigInteger subtraction in place
   * @param {BigInteger} x - Value to subtract
   */
  isub(x) {
    this.value.isub(x.value);
    return this;
  }

  /**
   * BigInteger subtraction
   * @param {BigInteger} x - Value to subtract
   * @returns {BigInteger} this - x.
   */
  sub(x) {
    return this.clone().isub(x);
  }

  /**
   * BigInteger multiplication in place
   * @param {BigInteger} x - Value to multiply
   */
  imul(x) {
    this.value.imul(x.value);
    return this;
  }

  /**
   * BigInteger multiplication
   * @param {BigInteger} x - Value to multiply
   * @returns {BigInteger} this * x.
   */
  mul(x) {
    return this.clone().imul(x);
  }

  /**
   * Compute value modulo m, in place
   * @param {BigInteger} m - Modulo
   */
  imod(m) {
    this.value = this.value.umod(m.value);
    return this;
  }

  /**
   * Compute value modulo m
   * @param {BigInteger} m - Modulo
   * @returns {BigInteger} this mod m.
   */
  mod(m) {
    return this.clone().imod(m);
  }

  /**
   * Compute modular exponentiation
   * Much faster than this.exp(e).mod(n)
   * @param {BigInteger} e - Exponent
   * @param {BigInteger} n - Modulo
   * @returns {BigInteger} this ** e mod n.
   */
  modExp(e, n) {
    // We use either Montgomery or normal reduction context
    // Montgomery requires coprime n and R (montogmery multiplier)
    //  bn.js picks R as power of 2, so n must be odd
    const nred = n.isEven() ? bn.red(n.value) : bn.mont(n.value);
    const x = this.clone();
    x.value = x.value.toRed(nred).redPow(e.value).fromRed();
    return x;
  }

  /**
   * Compute the inverse of this value modulo n
   * Note: this and and n must be relatively prime
   * @param {BigInteger} n - Modulo
   * @returns {BigInteger} x such that this*x = 1 mod n
   * @throws {Error} if the inverse does not exist
   */
  modInv(n) {
    // invm returns a wrong result if the inverse does not exist
    if (!this.gcd(n).isOne()) {
      throw new Error('Inverse does not exist');
    }
    return new BigInteger$1(this.value.invm(n.value));
  }

  /**
   * Compute greatest common divisor between this and n
   * @param {BigInteger} n - Operand
   * @returns {BigInteger} gcd
   */
  gcd(n) {
    return new BigInteger$1(this.value.gcd(n.value));
  }

  /**
   * Shift this to the left by x, in place
   * @param {BigInteger} x - Shift value
   */
  ileftShift(x) {
    this.value.ishln(x.value.toNumber());
    return this;
  }

  /**
   * Shift this to the left by x
   * @param {BigInteger} x - Shift value
   * @returns {BigInteger} this << x.
   */
  leftShift(x) {
    return this.clone().ileftShift(x);
  }

  /**
   * Shift this to the right by x, in place
   * @param {BigInteger} x - Shift value
   */
  irightShift(x) {
    this.value.ishrn(x.value.toNumber());
    return this;
  }

  /**
   * Shift this to the right by x
   * @param {BigInteger} x - Shift value
   * @returns {BigInteger} this >> x.
   */
  rightShift(x) {
    return this.clone().irightShift(x);
  }

  /**
   * Whether this value is equal to x
   * @param {BigInteger} x
   * @returns {Boolean}
   */
  equal(x) {
    return this.value.eq(x.value);
  }

  /**
   * Whether this value is less than x
   * @param {BigInteger} x
   * @returns {Boolean}
   */
  lt(x) {
    return this.value.lt(x.value);
  }

  /**
   * Whether this value is less than or equal to x
   * @param {BigInteger} x
   * @returns {Boolean}
   */
  lte(x) {
    return this.value.lte(x.value);
  }

  /**
   * Whether this value is greater than x
   * @param {BigInteger} x
   * @returns {Boolean}
   */
  gt(x) {
    return this.value.gt(x.value);
  }

  /**
   * Whether this value is greater than or equal to x
   * @param {BigInteger} x
   * @returns {Boolean}
   */
  gte(x) {
    return this.value.gte(x.value);
  }

  isZero() {
    return this.value.isZero();
  }

  isOne() {
    return this.value.eq(new bn(1));
  }

  isNegative() {
    return this.value.isNeg();
  }

  isEven() {
    return this.value.isEven();
  }

  abs() {
    const res = this.clone();
    res.value = res.value.abs();
    return res;
  }

  /**
   * Get this value as a string
   * @returns {String} this value.
   */
  toString() {
    return this.value.toString();
  }

  /**
   * Get this value as an exact Number (max 53 bits)
   * Fails if this value is too large
   * @returns {Number}
   */
  toNumber() {
    return this.value.toNumber();
  }

  /**
   * Get value of i-th bit
   * @param {Number} i - Bit index
   * @returns {Number} Bit value.
   */
  getBit(i) {
    return this.value.testn(i) ? 1 : 0;
  }

  /**
   * Compute bit length
   * @returns {Number} Bit length.
   */
  bitLength() {
    return this.value.bitLength();
  }

  /**
   * Compute byte length
   * @returns {Number} Byte length.
   */
  byteLength() {
    return this.value.byteLength();
  }

  /**
   * Get Uint8Array representation of this number
   * @param {String} endian - Endianess of output array (defaults to 'be')
   * @param {Number} length - Of output array
   * @returns {Uint8Array}
   */
  toUint8Array(endian = 'be', length) {
    return this.value.toArrayLike(Uint8Array, endian, length);
  }
}

var bn_interface = /*#__PURE__*/Object.freeze({
  __proto__: null,
  'default': BigInteger$1
});

var utils_1 = createCommonjsModule(function (module, exports) {

var utils = exports;

function toArray(msg, enc) {
  if (Array.isArray(msg))
    return msg.slice();
  if (!msg)
    return [];
  var res = [];
  if (typeof msg !== 'string') {
    for (var i = 0; i < msg.length; i++)
      res[i] = msg[i] | 0;
    return res;
  }
  if (enc === 'hex') {
    msg = msg.replace(/[^a-z0-9]+/ig, '');
    if (msg.length % 2 !== 0)
      msg = '0' + msg;
    for (var i = 0; i < msg.length; i += 2)
      res.push(parseInt(msg[i] + msg[i + 1], 16));
  } else {
    for (var i = 0; i < msg.length; i++) {
      var c = msg.charCodeAt(i);
      var hi = c >> 8;
      var lo = c & 0xff;
      if (hi)
        res.push(hi, lo);
      else
        res.push(lo);
    }
  }
  return res;
}
utils.toArray = toArray;

function zero2(word) {
  if (word.length === 1)
    return '0' + word;
  else
    return word;
}
utils.zero2 = zero2;

function toHex(msg) {
  var res = '';
  for (var i = 0; i < msg.length; i++)
    res += zero2(msg[i].toString(16));
  return res;
}
utils.toHex = toHex;

utils.encode = function encode(arr, enc) {
  if (enc === 'hex')
    return toHex(arr);
  else
    return arr;
};
});

var utils_1$1 = createCommonjsModule(function (module, exports) {

var utils = exports;




utils.assert = minimalisticAssert;
utils.toArray = utils_1.toArray;
utils.zero2 = utils_1.zero2;
utils.toHex = utils_1.toHex;
utils.encode = utils_1.encode;

// Represent num in a w-NAF form
function getNAF(num, w) {
  var naf = [];
  var ws = 1 << (w + 1);
  var k = num.clone();
  while (k.cmpn(1) >= 0) {
    var z;
    if (k.isOdd()) {
      var mod = k.andln(ws - 1);
      if (mod > (ws >> 1) - 1)
        z = (ws >> 1) - mod;
      else
        z = mod;
      k.isubn(z);
    } else {
      z = 0;
    }
    naf.push(z);

    // Optimization, shift by word if possible
    var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
    for (var i = 1; i < shift; i++)
      naf.push(0);
    k.iushrn(shift);
  }

  return naf;
}
utils.getNAF = getNAF;

// Represent k1, k2 in a Joint Sparse Form
function getJSF(k1, k2) {
  var jsf = [
    [],
    []
  ];

  k1 = k1.clone();
  k2 = k2.clone();
  var d1 = 0;
  var d2 = 0;
  while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {

    // First phase
    var m14 = (k1.andln(3) + d1) & 3;
    var m24 = (k2.andln(3) + d2) & 3;
    if (m14 === 3)
      m14 = -1;
    if (m24 === 3)
      m24 = -1;
    var u1;
    if ((m14 & 1) === 0) {
      u1 = 0;
    } else {
      var m8 = (k1.andln(7) + d1) & 7;
      if ((m8 === 3 || m8 === 5) && m24 === 2)
        u1 = -m14;
      else
        u1 = m14;
    }
    jsf[0].push(u1);

    var u2;
    if ((m24 & 1) === 0) {
      u2 = 0;
    } else {
      var m8 = (k2.andln(7) + d2) & 7;
      if ((m8 === 3 || m8 === 5) && m14 === 2)
        u2 = -m24;
      else
        u2 = m24;
    }
    jsf[1].push(u2);

    // Second phase
    if (2 * d1 === u1 + 1)
      d1 = 1 - d1;
    if (2 * d2 === u2 + 1)
      d2 = 1 - d2;
    k1.iushrn(1);
    k2.iushrn(1);
  }

  return jsf;
}
utils.getJSF = getJSF;

function cachedProperty(obj, name, computer) {
  var key = '_' + name;
  obj.prototype[name] = function cachedProperty() {
    return this[key] !== undefined ? this[key] :
           this[key] = computer.call(this);
  };
}
utils.cachedProperty = cachedProperty;

function parseBytes(bytes) {
  return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
                                     bytes;
}
utils.parseBytes = parseBytes;

function intFromLE(bytes) {
  return new bn(bytes, 'hex', 'le');
}
utils.intFromLE = intFromLE;
});

var r$1;

var brorand = function rand(len) {
  if (!r$1)
    r$1 = new Rand(null);

  return r$1.generate(len);
};

function Rand(rand) {
  this.rand = rand;
}
var Rand_1 = Rand;

Rand.prototype.generate = function generate(len) {
  return this._rand(len);
};

// Emulate crypto API using randy
Rand.prototype._rand = function _rand(n) {
  if (this.rand.getBytes)
    return this.rand.getBytes(n);

  var res = new Uint8Array(n);
  for (var i = 0; i < res.length; i++)
    res[i] = this.rand.getByte();
  return res;
};

if (typeof self === 'object') {
  if (self.crypto && self.crypto.getRandomValues) {
    // Modern browsers
    Rand.prototype._rand = function _rand(n) {
      var arr = new Uint8Array(n);
      self.crypto.getRandomValues(arr);
      return arr;
    };
  } else if (self.msCrypto && self.msCrypto.getRandomValues) {
    // IE
    Rand.prototype._rand = function _rand(n) {
      var arr = new Uint8Array(n);
      self.msCrypto.getRandomValues(arr);
      return arr;
    };

  // Safari's WebWorkers do not have `crypto`
  } else if (typeof window === 'object') {
    // Old junk
    Rand.prototype._rand = function() {
      throw new Error('Not implemented yet');
    };
  }
} else {
  // Node.js or Web worker with no crypto support
  try {
    var crypto$2 = crypto__default['default'];
    if (typeof crypto$2.randomBytes !== 'function')
      throw new Error('Not supported');

    Rand.prototype._rand = function _rand(n) {
      return crypto$2.randomBytes(n);
    };
  } catch (e) {
  }
}
brorand.Rand = Rand_1;

var getNAF = utils_1$1.getNAF;
var getJSF = utils_1$1.getJSF;
var assert$2 = utils_1$1.assert;

function BaseCurve(type, conf) {
  this.type = type;
  this.p = new bn(conf.p, 16);

  // Use Montgomery, when there is no fast reduction for the prime
  this.red = conf.prime ? bn.red(conf.prime) : bn.mont(this.p);

  // Useful for many curves
  this.zero = new bn(0).toRed(this.red);
  this.one = new bn(1).toRed(this.red);
  this.two = new bn(2).toRed(this.red);

  // Curve configuration, optional
  this.n = conf.n && new bn(conf.n, 16);
  this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);

  // Temporary arrays
  this._wnafT1 = new Array(4);
  this._wnafT2 = new Array(4);
  this._wnafT3 = new Array(4);
  this._wnafT4 = new Array(4);

  // Generalized Greg Maxwell's trick
  var adjustCount = this.n && this.p.div(this.n);
  if (!adjustCount || adjustCount.cmpn(100) > 0) {
    this.redN = null;
  } else {
    this._maxwellTrick = true;
    this.redN = this.n.toRed(this.red);
  }
}
var base = BaseCurve;

BaseCurve.prototype.point = function point() {
  throw new Error('Not implemented');
};

BaseCurve.prototype.validate = function validate() {
  throw new Error('Not implemented');
};

BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
  assert$2(p.precomputed);
  var doubles = p._getDoubles();

  var naf = getNAF(k, 1);
  var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
  I /= 3;

  // Translate into more windowed form
  var repr = [];
  for (var j = 0; j < naf.length; j += doubles.step) {
    var nafW = 0;
    for (var k = j + doubles.step - 1; k >= j; k--)
      nafW = (nafW << 1) + naf[k];
    repr.push(nafW);
  }

  var a = this.jpoint(null, null, null);
  var b = this.jpoint(null, null, null);
  for (var i = I; i > 0; i--) {
    for (var j = 0; j < repr.length; j++) {
      var nafW = repr[j];
      if (nafW === i)
        b = b.mixedAdd(doubles.points[j]);
      else if (nafW === -i)
        b = b.mixedAdd(doubles.points[j].neg());
    }
    a = a.add(b);
  }
  return a.toP();
};

BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
  var w = 4;

  // Precompute window
  var nafPoints = p._getNAFPoints(w);
  w = nafPoints.wnd;
  var wnd = nafPoints.points;

  // Get NAF form
  var naf = getNAF(k, w);

  // Add `this`*(N+1) for every w-NAF index
  var acc = this.jpoint(null, null, null);
  for (var i = naf.length - 1; i >= 0; i--) {
    // Count zeroes
    for (var k = 0; i >= 0 && naf[i] === 0; i--)
      k++;
    if (i >= 0)
      k++;
    acc = acc.dblp(k);

    if (i < 0)
      break;
    var z = naf[i];
    assert$2(z !== 0);
    if (p.type === 'affine') {
      // J +- P
      if (z > 0)
        acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
      else
        acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
    } else {
      // J +- J
      if (z > 0)
        acc = acc.add(wnd[(z - 1) >> 1]);
      else
        acc = acc.add(wnd[(-z - 1) >> 1].neg());
    }
  }
  return p.type === 'affine' ? acc.toP() : acc;
};

BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
                                                       points,
                                                       coeffs,
                                                       len,
                                                       jacobianResult) {
  var wndWidth = this._wnafT1;
  var wnd = this._wnafT2;
  var naf = this._wnafT3;

  // Fill all arrays
  var max = 0;
  for (var i = 0; i < len; i++) {
    var p = points[i];
    var nafPoints = p._getNAFPoints(defW);
    wndWidth[i] = nafPoints.wnd;
    wnd[i] = nafPoints.points;
  }

  // Comb small window NAFs
  for (var i = len - 1; i >= 1; i -= 2) {
    var a = i - 1;
    var b = i;
    if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
      naf[a] = getNAF(coeffs[a], wndWidth[a]);
      naf[b] = getNAF(coeffs[b], wndWidth[b]);
      max = Math.max(naf[a].length, max);
      max = Math.max(naf[b].length, max);
      continue;
    }

    var comb = [
      points[a], /* 1 */
      null, /* 3 */
      null, /* 5 */
      points[b] /* 7 */
    ];

    // Try to avoid Projective points, if possible
    if (points[a].y.cmp(points[b].y) === 0) {
      comb[1] = points[a].add(points[b]);
      comb[2] = points[a].toJ().mixedAdd(points[b].neg());
    } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
      comb[1] = points[a].toJ().mixedAdd(points[b]);
      comb[2] = points[a].add(points[b].neg());
    } else {
      comb[1] = points[a].toJ().mixedAdd(points[b]);
      comb[2] = points[a].toJ().mixedAdd(points[b].neg());
    }

    var index = [
      -3, /* -1 -1 */
      -1, /* -1 0 */
      -5, /* -1 1 */
      -7, /* 0 -1 */
      0, /* 0 0 */
      7, /* 0 1 */
      5, /* 1 -1 */
      1, /* 1 0 */
      3  /* 1 1 */
    ];

    var jsf = getJSF(coeffs[a], coeffs[b]);
    max = Math.max(jsf[0].length, max);
    naf[a] = new Array(max);
    naf[b] = new Array(max);
    for (var j = 0; j < max; j++) {
      var ja = jsf[0][j] | 0;
      var jb = jsf[1][j] | 0;

      naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
      naf[b][j] = 0;
      wnd[a] = comb;
    }
  }

  var acc = this.jpoint(null, null, null);
  var tmp = this._wnafT4;
  for (var i = max; i >= 0; i--) {
    var k = 0;

    while (i >= 0) {
      var zero = true;
      for (var j = 0; j < len; j++) {
        tmp[j] = naf[j][i] | 0;
        if (tmp[j] !== 0)
          zero = false;
      }
      if (!zero)
        break;
      k++;
      i--;
    }
    if (i >= 0)
      k++;
    acc = acc.dblp(k);
    if (i < 0)
      break;

    for (var j = 0; j < len; j++) {
      var z = tmp[j];
      var p;
      if (z === 0)
        continue;
      else if (z > 0)
        p = wnd[j][(z - 1) >> 1];
      else if (z < 0)
        p = wnd[j][(-z - 1) >> 1].neg();

      if (p.type === 'affine')
        acc = acc.mixedAdd(p);
      else
        acc = acc.add(p);
    }
  }
  // Zeroify references
  for (var i = 0; i < len; i++)
    wnd[i] = null;

  if (jacobianResult)
    return acc;
  else
    return acc.toP();
};

function BasePoint(curve, type) {
  this.curve = curve;
  this.type = type;
  this.precomputed = null;
}
BaseCurve.BasePoint = BasePoint;

BasePoint.prototype.eq = function eq(/*other*/) {
  throw new Error('Not implemented');
};

BasePoint.prototype.validate = function validate() {
  return this.curve.validate(this);
};

BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
  bytes = utils_1$1.toArray(bytes, enc);

  var len = this.p.byteLength();

  // uncompressed, hybrid-odd, hybrid-even
  if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
      bytes.length - 1 === 2 * len) {
    if (bytes[0] === 0x06)
      assert$2(bytes[bytes.length - 1] % 2 === 0);
    else if (bytes[0] === 0x07)
      assert$2(bytes[bytes.length - 1] % 2 === 1);

    var res =  this.point(bytes.slice(1, 1 + len),
                          bytes.slice(1 + len, 1 + 2 * len));

    return res;
  } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
              bytes.length - 1 === len) {
    return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
  }
  throw new Error('Unknown point format');
};

BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
  return this.encode(enc, true);
};

BasePoint.prototype._encode = function _encode(compact) {
  var len = this.curve.p.byteLength();
  var x = this.getX().toArray('be', len);

  if (compact)
    return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);

  return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
};

BasePoint.prototype.encode = function encode(enc, compact) {
  return utils_1$1.encode(this._encode(compact), enc);
};

BasePoint.prototype.precompute = function precompute(power) {
  if (this.precomputed)
    return this;

  var precomputed = {
    doubles: null,
    naf: null,
    beta: null
  };
  precomputed.naf = this._getNAFPoints(8);
  precomputed.doubles = this._getDoubles(4, power);
  precomputed.beta = this._getBeta();
  this.precomputed = precomputed;

  return this;
};

BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
  if (!this.precomputed)
    return false;

  var doubles = this.precomputed.doubles;
  if (!doubles)
    return false;

  return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
};

BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
  if (this.precomputed && this.precomputed.doubles)
    return this.precomputed.doubles;

  var doubles = [ this ];
  var acc = this;
  for (var i = 0; i < power; i += step) {
    for (var j = 0; j < step; j++)
      acc = acc.dbl();
    doubles.push(acc);
  }
  return {
    step: step,
    points: doubles
  };
};

BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
  if (this.precomputed && this.precomputed.naf)
    return this.precomputed.naf;

  var res = [ this ];
  var max = (1 << wnd) - 1;
  var dbl = max === 1 ? null : this.dbl();
  for (var i = 1; i < max; i++)
    res[i] = res[i - 1].add(dbl);
  return {
    wnd: wnd,
    points: res
  };
};

BasePoint.prototype._getBeta = function _getBeta() {
  return null;
};

BasePoint.prototype.dblp = function dblp(k) {
  var r = this;
  for (var i = 0; i < k; i++)
    r = r.dbl();
  return r;
};

var assert$3 = utils_1$1.assert;

function ShortCurve(conf) {
  base.call(this, 'short', conf);

  this.a = new bn(conf.a, 16).toRed(this.red);
  this.b = new bn(conf.b, 16).toRed(this.red);
  this.tinv = this.two.redInvm();

  this.zeroA = this.a.fromRed().cmpn(0) === 0;
  this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;

  // If the curve is endomorphic, precalculate beta and lambda
  this.endo = this._getEndomorphism(conf);
  this._endoWnafT1 = new Array(4);
  this._endoWnafT2 = new Array(4);
}
inherits(ShortCurve, base);
var short_1 = ShortCurve;

ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
  // No efficient endomorphism
  if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
    return;

  // Compute beta and lambda, that lambda * P = (beta * Px; Py)
  var beta;
  var lambda;
  if (conf.beta) {
    beta = new bn(conf.beta, 16).toRed(this.red);
  } else {
    var betas = this._getEndoRoots(this.p);
    // Choose the smallest beta
    beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
    beta = beta.toRed(this.red);
  }
  if (conf.lambda) {
    lambda = new bn(conf.lambda, 16);
  } else {
    // Choose the lambda that is matching selected beta
    var lambdas = this._getEndoRoots(this.n);
    if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
      lambda = lambdas[0];
    } else {
      lambda = lambdas[1];
      assert$3(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
    }
  }

  // Get basis vectors, used for balanced length-two representation
  var basis;
  if (conf.basis) {
    basis = conf.basis.map(function(vec) {
      return {
        a: new bn(vec.a, 16),
        b: new bn(vec.b, 16)
      };
    });
  } else {
    basis = this._getEndoBasis(lambda);
  }

  return {
    beta: beta,
    lambda: lambda,
    basis: basis
  };
};

ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
  // Find roots of for x^2 + x + 1 in F
  // Root = (-1 +- Sqrt(-3)) / 2
  //
  var red = num === this.p ? this.red : bn.mont(num);
  var tinv = new bn(2).toRed(red).redInvm();
  var ntinv = tinv.redNeg();

  var s = new bn(3).toRed(red).redNeg().redSqrt().redMul(tinv);

  var l1 = ntinv.redAdd(s).fromRed();
  var l2 = ntinv.redSub(s).fromRed();
  return [ l1, l2 ];
};

ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
  // aprxSqrt >= sqrt(this.n)
  var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));

  // 3.74
  // Run EGCD, until r(L + 1) < aprxSqrt
  var u = lambda;
  var v = this.n.clone();
  var x1 = new bn(1);
  var y1 = new bn(0);
  var x2 = new bn(0);
  var y2 = new bn(1);

  // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
  var a0;
  var b0;
  // First vector
  var a1;
  var b1;
  // Second vector
  var a2;
  var b2;

  var prevR;
  var i = 0;
  var r;
  var x;
  while (u.cmpn(0) !== 0) {
    var q = v.div(u);
    r = v.sub(q.mul(u));
    x = x2.sub(q.mul(x1));
    var y = y2.sub(q.mul(y1));

    if (!a1 && r.cmp(aprxSqrt) < 0) {
      a0 = prevR.neg();
      b0 = x1;
      a1 = r.neg();
      b1 = x;
    } else if (a1 && ++i === 2) {
      break;
    }
    prevR = r;

    v = u;
    u = r;
    x2 = x1;
    x1 = x;
    y2 = y1;
    y1 = y;
  }
  a2 = r.neg();
  b2 = x;

  var len1 = a1.sqr().add(b1.sqr());
  var len2 = a2.sqr().add(b2.sqr());
  if (len2.cmp(len1) >= 0) {
    a2 = a0;
    b2 = b0;
  }

  // Normalize signs
  if (a1.negative) {
    a1 = a1.neg();
    b1 = b1.neg();
  }
  if (a2.negative) {
    a2 = a2.neg();
    b2 = b2.neg();
  }

  return [
    { a: a1, b: b1 },
    { a: a2, b: b2 }
  ];
};

ShortCurve.prototype._endoSplit = function _endoSplit(k) {
  var basis = this.endo.basis;
  var v1 = basis[0];
  var v2 = basis[1];

  var c1 = v2.b.mul(k).divRound(this.n);
  var c2 = v1.b.neg().mul(k).divRound(this.n);

  var p1 = c1.mul(v1.a);
  var p2 = c2.mul(v2.a);
  var q1 = c1.mul(v1.b);
  var q2 = c2.mul(v2.b);

  // Calculate answer
  var k1 = k.sub(p1).sub(p2);
  var k2 = q1.add(q2).neg();
  return { k1: k1, k2: k2 };
};

ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
  x = new bn(x, 16);
  if (!x.red)
    x = x.toRed(this.red);

  var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
  var y = y2.redSqrt();
  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
    throw new Error('invalid point');

  // XXX Is there any way to tell if the number is odd without converting it
  // to non-red form?
  var isOdd = y.fromRed().isOdd();
  if (odd && !isOdd || !odd && isOdd)
    y = y.redNeg();

  return this.point(x, y);
};

ShortCurve.prototype.validate = function validate(point) {
  if (point.inf)
    return true;

  var x = point.x;
  var y = point.y;

  var ax = this.a.redMul(x);
  var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
  return y.redSqr().redISub(rhs).cmpn(0) === 0;
};

ShortCurve.prototype._endoWnafMulAdd =
    function _endoWnafMulAdd(points, coeffs, jacobianResult) {
  var npoints = this._endoWnafT1;
  var ncoeffs = this._endoWnafT2;
  for (var i = 0; i < points.length; i++) {
    var split = this._endoSplit(coeffs[i]);
    var p = points[i];
    var beta = p._getBeta();

    if (split.k1.negative) {
      split.k1.ineg();
      p = p.neg(true);
    }
    if (split.k2.negative) {
      split.k2.ineg();
      beta = beta.neg(true);
    }

    npoints[i * 2] = p;
    npoints[i * 2 + 1] = beta;
    ncoeffs[i * 2] = split.k1;
    ncoeffs[i * 2 + 1] = split.k2;
  }
  var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);

  // Clean-up references to points and coefficients
  for (var j = 0; j < i * 2; j++) {
    npoints[j] = null;
    ncoeffs[j] = null;
  }
  return res;
};

function Point(curve, x, y, isRed) {
  base.BasePoint.call(this, curve, 'affine');
  if (x === null && y === null) {
    this.x = null;
    this.y = null;
    this.inf = true;
  } else {
    this.x = new bn(x, 16);
    this.y = new bn(y, 16);
    // Force redgomery representation when loading from JSON
    if (isRed) {
      this.x.forceRed(this.curve.red);
      this.y.forceRed(this.curve.red);
    }
    if (!this.x.red)
      this.x = this.x.toRed(this.curve.red);
    if (!this.y.red)
      this.y = this.y.toRed(this.curve.red);
    this.inf = false;
  }
}
inherits(Point, base.BasePoint);

ShortCurve.prototype.point = function point(x, y, isRed) {
  return new Point(this, x, y, isRed);
};

ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
  return Point.fromJSON(this, obj, red);
};

Point.prototype._getBeta = function _getBeta() {
  if (!this.curve.endo)
    return;

  var pre = this.precomputed;
  if (pre && pre.beta)
    return pre.beta;

  var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
  if (pre) {
    var curve = this.curve;
    var endoMul = function(p) {
      return curve.point(p.x.redMul(curve.endo.beta), p.y);
    };
    pre.beta = beta;
    beta.precomputed = {
      beta: null,
      naf: pre.naf && {
        wnd: pre.naf.wnd,
        points: pre.naf.points.map(endoMul)
      },
      doubles: pre.doubles && {
        step: pre.doubles.step,
        points: pre.doubles.points.map(endoMul)
      }
    };
  }
  return beta;
};

Point.prototype.toJSON = function toJSON() {
  if (!this.precomputed)
    return [ this.x, this.y ];

  return [ this.x, this.y, this.precomputed && {
    doubles: this.precomputed.doubles && {
      step: this.precomputed.doubles.step,
      points: this.precomputed.doubles.points.slice(1)
    },
    naf: this.precomputed.naf && {
      wnd: this.precomputed.naf.wnd,
      points: this.precomputed.naf.points.slice(1)
    }
  } ];
};

Point.fromJSON = function fromJSON(curve, obj, red) {
  if (typeof obj === 'string')
    obj = JSON.parse(obj);
  var res = curve.point(obj[0], obj[1], red);
  if (!obj[2])
    return res;

  function obj2point(obj) {
    return curve.point(obj[0], obj[1], red);
  }

  var pre = obj[2];
  res.precomputed = {
    beta: null,
    doubles: pre.doubles && {
      step: pre.doubles.step,
      points: [ res ].concat(pre.doubles.points.map(obj2point))
    },
    naf: pre.naf && {
      wnd: pre.naf.wnd,
      points: [ res ].concat(pre.naf.points.map(obj2point))
    }
  };
  return res;
};

Point.prototype.inspect = function inspect() {
  if (this.isInfinity())
    return '<EC Point Infinity>';
  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
      ' y: ' + this.y.fromRed().toString(16, 2) + '>';
};

Point.prototype.isInfinity = function isInfinity() {
  return this.inf;
};

Point.prototype.add = function add(p) {
  // O + P = P
  if (this.inf)
    return p;

  // P + O = P
  if (p.inf)
    return this;

  // P + P = 2P
  if (this.eq(p))
    return this.dbl();

  // P + (-P) = O
  if (this.neg().eq(p))
    return this.curve.point(null, null);

  // P + Q = O
  if (this.x.cmp(p.x) === 0)
    return this.curve.point(null, null);

  var c = this.y.redSub(p.y);
  if (c.cmpn(0) !== 0)
    c = c.redMul(this.x.redSub(p.x).redInvm());
  var nx = c.redSqr().redISub(this.x).redISub(p.x);
  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
  return this.curve.point(nx, ny);
};

Point.prototype.dbl = function dbl() {
  if (this.inf)
    return this;

  // 2P = O
  var ys1 = this.y.redAdd(this.y);
  if (ys1.cmpn(0) === 0)
    return this.curve.point(null, null);

  var a = this.curve.a;

  var x2 = this.x.redSqr();
  var dyinv = ys1.redInvm();
  var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);

  var nx = c.redSqr().redISub(this.x.redAdd(this.x));
  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
  return this.curve.point(nx, ny);
};

Point.prototype.getX = function getX() {
  return this.x.fromRed();
};

Point.prototype.getY = function getY() {
  return this.y.fromRed();
};

Point.prototype.mul = function mul(k) {
  k = new bn(k, 16);
  if (this.isInfinity())
    return this;
  else if (this._hasDoubles(k))
    return this.curve._fixedNafMul(this, k);
  else if (this.curve.endo)
    return this.curve._endoWnafMulAdd([ this ], [ k ]);
  else
    return this.curve._wnafMul(this, k);
};

Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
  var points = [ this, p2 ];
  var coeffs = [ k1, k2 ];
  if (this.curve.endo)
    return this.curve._endoWnafMulAdd(points, coeffs);
  else
    return this.curve._wnafMulAdd(1, points, coeffs, 2);
};

Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
  var points = [ this, p2 ];
  var coeffs = [ k1, k2 ];
  if (this.curve.endo)
    return this.curve._endoWnafMulAdd(points, coeffs, true);
  else
    return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
};

Point.prototype.eq = function eq(p) {
  return this === p ||
         this.inf === p.inf &&
             (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
};

Point.prototype.neg = function neg(_precompute) {
  if (this.inf)
    return this;

  var res = this.curve.point(this.x, this.y.redNeg());
  if (_precompute && this.precomputed) {
    var pre = this.precomputed;
    var negate = function(p) {
      return p.neg();
    };
    res.precomputed = {
      naf: pre.naf && {
        wnd: pre.naf.wnd,
        points: pre.naf.points.map(negate)
      },
      doubles: pre.doubles && {
        step: pre.doubles.step,
        points: pre.doubles.points.map(negate)
      }
    };
  }
  return res;
};

Point.prototype.toJ = function toJ() {
  if (this.inf)
    return this.curve.jpoint(null, null, null);

  var res = this.curve.jpoint(this.x, this.y, this.curve.one);
  return res;
};

function JPoint(curve, x, y, z) {
  base.BasePoint.call(this, curve, 'jacobian');
  if (x === null && y === null && z === null) {
    this.x = this.curve.one;
    this.y = this.curve.one;
    this.z = new bn(0);
  } else {
    this.x = new bn(x, 16);
    this.y = new bn(y, 16);
    this.z = new bn(z, 16);
  }
  if (!this.x.red)
    this.x = this.x.toRed(this.curve.red);
  if (!this.y.red)
    this.y = this.y.toRed(this.curve.red);
  if (!this.z.red)
    this.z = this.z.toRed(this.curve.red);

  this.zOne = this.z === this.curve.one;
}
inherits(JPoint, base.BasePoint);

ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
  return new JPoint(this, x, y, z);
};

JPoint.prototype.toP = function toP() {
  if (this.isInfinity())
    return this.curve.point(null, null);

  var zinv = this.z.redInvm();
  var zinv2 = zinv.redSqr();
  var ax = this.x.redMul(zinv2);
  var ay = this.y.redMul(zinv2).redMul(zinv);

  return this.curve.point(ax, ay);
};

JPoint.prototype.neg = function neg() {
  return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
};

JPoint.prototype.add = function add(p) {
  // O + P = P
  if (this.isInfinity())
    return p;

  // P + O = P
  if (p.isInfinity())
    return this;

  // 12M + 4S + 7A
  var pz2 = p.z.redSqr();
  var z2 = this.z.redSqr();
  var u1 = this.x.redMul(pz2);
  var u2 = p.x.redMul(z2);
  var s1 = this.y.redMul(pz2.redMul(p.z));
  var s2 = p.y.redMul(z2.redMul(this.z));

  var h = u1.redSub(u2);
  var r = s1.redSub(s2);
  if (h.cmpn(0) === 0) {
    if (r.cmpn(0) !== 0)
      return this.curve.jpoint(null, null, null);
    else
      return this.dbl();
  }

  var h2 = h.redSqr();
  var h3 = h2.redMul(h);
  var v = u1.redMul(h2);

  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
  var nz = this.z.redMul(p.z).redMul(h);

  return this.curve.jpoint(nx, ny, nz);
};

JPoint.prototype.mixedAdd = function mixedAdd(p) {
  // O + P = P
  if (this.isInfinity())
    return p.toJ();

  // P + O = P
  if (p.isInfinity())
    return this;

  // 8M + 3S + 7A
  var z2 = this.z.redSqr();
  var u1 = this.x;
  var u2 = p.x.redMul(z2);
  var s1 = this.y;
  var s2 = p.y.redMul(z2).redMul(this.z);

  var h = u1.redSub(u2);
  var r = s1.redSub(s2);
  if (h.cmpn(0) === 0) {
    if (r.cmpn(0) !== 0)
      return this.curve.jpoint(null, null, null);
    else
      return this.dbl();
  }

  var h2 = h.redSqr();
  var h3 = h2.redMul(h);
  var v = u1.redMul(h2);

  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
  var nz = this.z.redMul(h);

  return this.curve.jpoint(nx, ny, nz);
};

JPoint.prototype.dblp = function dblp(pow) {
  if (pow === 0)
    return this;
  if (this.isInfinity())
    return this;
  if (!pow)
    return this.dbl();

  if (this.curve.zeroA || this.curve.threeA) {
    var r = this;
    for (var i = 0; i < pow; i++)
      r = r.dbl();
    return r;
  }

  // 1M + 2S + 1A + N * (4S + 5M + 8A)
  // N = 1 => 6M + 6S + 9A
  var a = this.curve.a;
  var tinv = this.curve.tinv;

  var jx = this.x;
  var jy = this.y;
  var jz = this.z;
  var jz4 = jz.redSqr().redSqr();

  // Reuse results
  var jyd = jy.redAdd(jy);
  for (var i = 0; i < pow; i++) {
    var jx2 = jx.redSqr();
    var jyd2 = jyd.redSqr();
    var jyd4 = jyd2.redSqr();
    var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));

    var t1 = jx.redMul(jyd2);
    var nx = c.redSqr().redISub(t1.redAdd(t1));
    var t2 = t1.redISub(nx);
    var dny = c.redMul(t2);
    dny = dny.redIAdd(dny).redISub(jyd4);
    var nz = jyd.redMul(jz);
    if (i + 1 < pow)
      jz4 = jz4.redMul(jyd4);

    jx = nx;
    jz = nz;
    jyd = dny;
  }

  return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
};

JPoint.prototype.dbl = function dbl() {
  if (this.isInfinity())
    return this;

  if (this.curve.zeroA)
    return this._zeroDbl();
  else if (this.curve.threeA)
    return this._threeDbl();
  else
    return this._dbl();
};

JPoint.prototype._zeroDbl = function _zeroDbl() {
  var nx;
  var ny;
  var nz;
  // Z = 1
  if (this.zOne) {
    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
    //     #doubling-mdbl-2007-bl
    // 1M + 5S + 14A

    // XX = X1^2
    var xx = this.x.redSqr();
    // YY = Y1^2
    var yy = this.y.redSqr();
    // YYYY = YY^2
    var yyyy = yy.redSqr();
    // S = 2 * ((X1 + YY)^2 - XX - YYYY)
    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
    s = s.redIAdd(s);
    // M = 3 * XX + a; a = 0
    var m = xx.redAdd(xx).redIAdd(xx);
    // T = M ^ 2 - 2*S
    var t = m.redSqr().redISub(s).redISub(s);

    // 8 * YYYY
    var yyyy8 = yyyy.redIAdd(yyyy);
    yyyy8 = yyyy8.redIAdd(yyyy8);
    yyyy8 = yyyy8.redIAdd(yyyy8);

    // X3 = T
    nx = t;
    // Y3 = M * (S - T) - 8 * YYYY
    ny = m.redMul(s.redISub(t)).redISub(yyyy8);
    // Z3 = 2*Y1
    nz = this.y.redAdd(this.y);
  } else {
    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
    //     #doubling-dbl-2009-l
    // 2M + 5S + 13A

    // A = X1^2
    var a = this.x.redSqr();
    // B = Y1^2
    var b = this.y.redSqr();
    // C = B^2
    var c = b.redSqr();
    // D = 2 * ((X1 + B)^2 - A - C)
    var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
    d = d.redIAdd(d);
    // E = 3 * A
    var e = a.redAdd(a).redIAdd(a);
    // F = E^2
    var f = e.redSqr();

    // 8 * C
    var c8 = c.redIAdd(c);
    c8 = c8.redIAdd(c8);
    c8 = c8.redIAdd(c8);

    // X3 = F - 2 * D
    nx = f.redISub(d).redISub(d);
    // Y3 = E * (D - X3) - 8 * C
    ny = e.redMul(d.redISub(nx)).redISub(c8);
    // Z3 = 2 * Y1 * Z1
    nz = this.y.redMul(this.z);
    nz = nz.redIAdd(nz);
  }

  return this.curve.jpoint(nx, ny, nz);
};

JPoint.prototype._threeDbl = function _threeDbl() {
  var nx;
  var ny;
  var nz;
  // Z = 1
  if (this.zOne) {
    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
    //     #doubling-mdbl-2007-bl
    // 1M + 5S + 15A

    // XX = X1^2
    var xx = this.x.redSqr();
    // YY = Y1^2
    var yy = this.y.redSqr();
    // YYYY = YY^2
    var yyyy = yy.redSqr();
    // S = 2 * ((X1 + YY)^2 - XX - YYYY)
    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
    s = s.redIAdd(s);
    // M = 3 * XX + a
    var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
    // T = M^2 - 2 * S
    var t = m.redSqr().redISub(s).redISub(s);
    // X3 = T
    nx = t;
    // Y3 = M * (S - T) - 8 * YYYY
    var yyyy8 = yyyy.redIAdd(yyyy);
    yyyy8 = yyyy8.redIAdd(yyyy8);
    yyyy8 = yyyy8.redIAdd(yyyy8);
    ny = m.redMul(s.redISub(t)).redISub(yyyy8);
    // Z3 = 2 * Y1
    nz = this.y.redAdd(this.y);
  } else {
    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
    // 3M + 5S

    // delta = Z1^2
    var delta = this.z.redSqr();
    // gamma = Y1^2
    var gamma = this.y.redSqr();
    // beta = X1 * gamma
    var beta = this.x.redMul(gamma);
    // alpha = 3 * (X1 - delta) * (X1 + delta)
    var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
    alpha = alpha.redAdd(alpha).redIAdd(alpha);
    // X3 = alpha^2 - 8 * beta
    var beta4 = beta.redIAdd(beta);
    beta4 = beta4.redIAdd(beta4);
    var beta8 = beta4.redAdd(beta4);
    nx = alpha.redSqr().redISub(beta8);
    // Z3 = (Y1 + Z1)^2 - gamma - delta
    nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
    // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
    var ggamma8 = gamma.redSqr();
    ggamma8 = ggamma8.redIAdd(ggamma8);
    ggamma8 = ggamma8.redIAdd(ggamma8);
    ggamma8 = ggamma8.redIAdd(ggamma8);
    ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
  }

  return this.curve.jpoint(nx, ny, nz);
};

JPoint.prototype._dbl = function _dbl() {
  var a = this.curve.a;

  // 4M + 6S + 10A
  var jx = this.x;
  var jy = this.y;
  var jz = this.z;
  var jz4 = jz.redSqr().redSqr();

  var jx2 = jx.redSqr();
  var jy2 = jy.redSqr();

  var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));

  var jxd4 = jx.redAdd(jx);
  jxd4 = jxd4.redIAdd(jxd4);
  var t1 = jxd4.redMul(jy2);
  var nx = c.redSqr().redISub(t1.redAdd(t1));
  var t2 = t1.redISub(nx);

  var jyd8 = jy2.redSqr();
  jyd8 = jyd8.redIAdd(jyd8);
  jyd8 = jyd8.redIAdd(jyd8);
  jyd8 = jyd8.redIAdd(jyd8);
  var ny = c.redMul(t2).redISub(jyd8);
  var nz = jy.redAdd(jy).redMul(jz);

  return this.curve.jpoint(nx, ny, nz);
};

JPoint.prototype.trpl = function trpl() {
  if (!this.curve.zeroA)
    return this.dbl().add(this);

  // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
  // 5M + 10S + ...

  // XX = X1^2
  var xx = this.x.redSqr();
  // YY = Y1^2
  var yy = this.y.redSqr();
  // ZZ = Z1^2
  var zz = this.z.redSqr();
  // YYYY = YY^2
  var yyyy = yy.redSqr();
  // M = 3 * XX + a * ZZ2; a = 0
  var m = xx.redAdd(xx).redIAdd(xx);
  // MM = M^2
  var mm = m.redSqr();
  // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
  var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
  e = e.redIAdd(e);
  e = e.redAdd(e).redIAdd(e);
  e = e.redISub(mm);
  // EE = E^2
  var ee = e.redSqr();
  // T = 16*YYYY
  var t = yyyy.redIAdd(yyyy);
  t = t.redIAdd(t);
  t = t.redIAdd(t);
  t = t.redIAdd(t);
  // U = (M + E)^2 - MM - EE - T
  var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
  // X3 = 4 * (X1 * EE - 4 * YY * U)
  var yyu4 = yy.redMul(u);
  yyu4 = yyu4.redIAdd(yyu4);
  yyu4 = yyu4.redIAdd(yyu4);
  var nx = this.x.redMul(ee).redISub(yyu4);
  nx = nx.redIAdd(nx);
  nx = nx.redIAdd(nx);
  // Y3 = 8 * Y1 * (U * (T - U) - E * EE)
  var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
  ny = ny.redIAdd(ny);
  ny = ny.redIAdd(ny);
  ny = ny.redIAdd(ny);
  // Z3 = (Z1 + E)^2 - ZZ - EE
  var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);

  return this.curve.jpoint(nx, ny, nz);
};

JPoint.prototype.mul = function mul(k, kbase) {
  k = new bn(k, kbase);

  return this.curve._wnafMul(this, k);
};

JPoint.prototype.eq = function eq(p) {
  if (p.type === 'affine')
    return this.eq(p.toJ());

  if (this === p)
    return true;

  // x1 * z2^2 == x2 * z1^2
  var z2 = this.z.redSqr();
  var pz2 = p.z.redSqr();
  if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
    return false;

  // y1 * z2^3 == y2 * z1^3
  var z3 = z2.redMul(this.z);
  var pz3 = pz2.redMul(p.z);
  return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
};

JPoint.prototype.eqXToP = function eqXToP(x) {
  var zs = this.z.redSqr();
  var rx = x.toRed(this.curve.red).redMul(zs);
  if (this.x.cmp(rx) === 0)
    return true;

  var xc = x.clone();
  var t = this.curve.redN.redMul(zs);
  for (;;) {
    xc.iadd(this.curve.n);
    if (xc.cmp(this.curve.p) >= 0)
      return false;

    rx.redIAdd(t);
    if (this.x.cmp(rx) === 0)
      return true;
  }
};

JPoint.prototype.inspect = function inspect() {
  if (this.isInfinity())
    return '<EC JPoint Infinity>';
  return '<EC JPoint x: ' + this.x.toString(16, 2) +
      ' y: ' + this.y.toString(16, 2) +
      ' z: ' + this.z.toString(16, 2) + '>';
};

JPoint.prototype.isInfinity = function isInfinity() {
  // XXX This code assumes that zero is always zero in red
  return this.z.cmpn(0) === 0;
};

function MontCurve(conf) {
  base.call(this, 'mont', conf);

  this.a = new bn(conf.a, 16).toRed(this.red);
  this.b = new bn(conf.b, 16).toRed(this.red);
  this.i4 = new bn(4).toRed(this.red).redInvm();
  this.two = new bn(2).toRed(this.red);
  // Note: this implementation is according to the original paper
  // by P. Montgomery, NOT the one by D. J. Bernstein.
  this.a24 = this.i4.redMul(this.a.redAdd(this.two));
}
inherits(MontCurve, base);
var mont = MontCurve;

MontCurve.prototype.validate = function validate(point) {
  var x = point.normalize().x;
  var x2 = x.redSqr();
  var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
  var y = rhs.redSqrt();

  return y.redSqr().cmp(rhs) === 0;
};

function Point$1(curve, x, z) {
  base.BasePoint.call(this, curve, 'projective');
  if (x === null && z === null) {
    this.x = this.curve.one;
    this.z = this.curve.zero;
  } else {
    this.x = new bn(x, 16);
    this.z = new bn(z, 16);
    if (!this.x.red)
      this.x = this.x.toRed(this.curve.red);
    if (!this.z.red)
      this.z = this.z.toRed(this.curve.red);
  }
}
inherits(Point$1, base.BasePoint);

MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
  var bytes = utils_1$1.toArray(bytes, enc);

  // TODO Curve448
  // Montgomery curve points must be represented in the compressed format
  // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B
  if (bytes.length === 33 && bytes[0] === 0x40)
    bytes = bytes.slice(1, 33).reverse(); // point must be little-endian
  if (bytes.length !== 32)
    throw new Error('Unknown point compression format');
  return this.point(bytes, 1);
};

MontCurve.prototype.point = function point(x, z) {
  return new Point$1(this, x, z);
};

MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
  return Point$1.fromJSON(this, obj);
};

Point$1.prototype.precompute = function precompute() {
  // No-op
};

Point$1.prototype._encode = function _encode(compact) {
  var len = this.curve.p.byteLength();

  // Note: the output should always be little-endian
  // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B
  if (compact) {
    return [ 0x40 ].concat(this.getX().toArray('le', len));
  } else {
    return this.getX().toArray('be', len);
  }
};

Point$1.fromJSON = function fromJSON(curve, obj) {
  return new Point$1(curve, obj[0], obj[1] || curve.one);
};

Point$1.prototype.inspect = function inspect() {
  if (this.isInfinity())
    return '<EC Point Infinity>';
  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
      ' z: ' + this.z.fromRed().toString(16, 2) + '>';
};

Point$1.prototype.isInfinity = function isInfinity() {
  // XXX This code assumes that zero is always zero in red
  return this.z.cmpn(0) === 0;
};

Point$1.prototype.dbl = function dbl() {
  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
  // 2M + 2S + 4A

  // A = X1 + Z1
  var a = this.x.redAdd(this.z);
  // AA = A^2
  var aa = a.redSqr();
  // B = X1 - Z1
  var b = this.x.redSub(this.z);
  // BB = B^2
  var bb = b.redSqr();
  // C = AA - BB
  var c = aa.redSub(bb);
  // X3 = AA * BB
  var nx = aa.redMul(bb);
  // Z3 = C * (BB + A24 * C)
  var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
  return this.curve.point(nx, nz);
};

Point$1.prototype.add = function add() {
  throw new Error('Not supported on Montgomery curve');
};

Point$1.prototype.diffAdd = function diffAdd(p, diff) {
  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
  // 4M + 2S + 6A

  // A = X2 + Z2
  var a = this.x.redAdd(this.z);
  // B = X2 - Z2
  var b = this.x.redSub(this.z);
  // C = X3 + Z3
  var c = p.x.redAdd(p.z);
  // D = X3 - Z3
  var d = p.x.redSub(p.z);
  // DA = D * A
  var da = d.redMul(a);
  // CB = C * B
  var cb = c.redMul(b);
  // X5 = Z1 * (DA + CB)^2
  var nx = diff.z.redMul(da.redAdd(cb).redSqr());
  // Z5 = X1 * (DA - CB)^2
  var nz = diff.x.redMul(da.redISub(cb).redSqr());
  return this.curve.point(nx, nz);
};

Point$1.prototype.mul = function mul(k) {
  k = new bn(k, 16);

  var t = k.clone();
  var a = this; // (N / 2) * Q + Q
  var b = this.curve.point(null, null); // (N / 2) * Q
  var c = this; // Q

  for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
    bits.push(t.andln(1));

  for (var i = bits.length - 1; i >= 0; i--) {
    if (bits[i] === 0) {
      // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
      a = a.diffAdd(b, c);
      // N * Q = 2 * ((N / 2) * Q + Q))
      b = b.dbl();
    } else {
      // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
      b = a.diffAdd(b, c);
      // N * Q + Q = 2 * ((N / 2) * Q + Q)
      a = a.dbl();
    }
  }
  return b;
};

Point$1.prototype.mulAdd = function mulAdd() {
  throw new Error('Not supported on Montgomery curve');
};

Point$1.prototype.jumlAdd = function jumlAdd() {
  throw new Error('Not supported on Montgomery curve');
};

Point$1.prototype.eq = function eq(other) {
  return this.getX().cmp(other.getX()) === 0;
};

Point$1.prototype.normalize = function normalize() {
  this.x = this.x.redMul(this.z.redInvm());
  this.z = this.curve.one;
  return this;
};

Point$1.prototype.getX = function getX() {
  // Normalize coordinates
  this.normalize();

  return this.x.fromRed();
};

var assert$4 = utils_1$1.assert;

function EdwardsCurve(conf) {
  // NOTE: Important as we are creating point in Base.call()
  this.twisted = (conf.a | 0) !== 1;
  this.mOneA = this.twisted && (conf.a | 0) === -1;
  this.extended = this.mOneA;

  base.call(this, 'edwards', conf);

  this.a = new bn(conf.a, 16).umod(this.red.m);
  this.a = this.a.toRed(this.red);
  this.c = new bn(conf.c, 16).toRed(this.red);
  this.c2 = this.c.redSqr();
  this.d = new bn(conf.d, 16).toRed(this.red);
  this.dd = this.d.redAdd(this.d);

  assert$4(!this.twisted || this.c.fromRed().cmpn(1) === 0);
  this.oneC = (conf.c | 0) === 1;
}
inherits(EdwardsCurve, base);
var edwards = EdwardsCurve;

EdwardsCurve.prototype._mulA = function _mulA(num) {
  if (this.mOneA)
    return num.redNeg();
  else
    return this.a.redMul(num);
};

EdwardsCurve.prototype._mulC = function _mulC(num) {
  if (this.oneC)
    return num;
  else
    return this.c.redMul(num);
};

// Just for compatibility with Short curve
EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
  return this.point(x, y, z, t);
};

EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
  x = new bn(x, 16);
  if (!x.red)
    x = x.toRed(this.red);

  var x2 = x.redSqr();
  var rhs = this.c2.redSub(this.a.redMul(x2));
  var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));

  var y2 = rhs.redMul(lhs.redInvm());
  var y = y2.redSqrt();
  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
    throw new Error('invalid point');

  var isOdd = y.fromRed().isOdd();
  if (odd && !isOdd || !odd && isOdd)
    y = y.redNeg();

  return this.point(x, y);
};

EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
  y = new bn(y, 16);
  if (!y.red)
    y = y.toRed(this.red);

  // x^2 = (y^2 - c^2) / (c^2 d y^2 - a)
  var y2 = y.redSqr();
  var lhs = y2.redSub(this.c2);
  var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a);
  var x2 = lhs.redMul(rhs.redInvm());

  if (x2.cmp(this.zero) === 0) {
    if (odd)
      throw new Error('invalid point');
    else
      return this.point(this.zero, y);
  }

  var x = x2.redSqrt();
  if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
    throw new Error('invalid point');

  if (x.fromRed().isOdd() !== odd)
    x = x.redNeg();

  return this.point(x, y);
};

EdwardsCurve.prototype.validate = function validate(point) {
  if (point.isInfinity())
    return true;

  // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
  point.normalize();

  var x2 = point.x.redSqr();
  var y2 = point.y.redSqr();
  var lhs = x2.redMul(this.a).redAdd(y2);
  var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));

  return lhs.cmp(rhs) === 0;
};

function Point$2(curve, x, y, z, t) {
  base.BasePoint.call(this, curve, 'projective');
  if (x === null && y === null && z === null) {
    this.x = this.curve.zero;
    this.y = this.curve.one;
    this.z = this.curve.one;
    this.t = this.curve.zero;
    this.zOne = true;
  } else {
    this.x = new bn(x, 16);
    this.y = new bn(y, 16);
    this.z = z ? new bn(z, 16) : this.curve.one;
    this.t = t && new bn(t, 16);
    if (!this.x.red)
      this.x = this.x.toRed(this.curve.red);
    if (!this.y.red)
      this.y = this.y.toRed(this.curve.red);
    if (!this.z.red)
      this.z = this.z.toRed(this.curve.red);
    if (this.t && !this.t.red)
      this.t = this.t.toRed(this.curve.red);
    this.zOne = this.z === this.curve.one;

    // Use extended coordinates
    if (this.curve.extended && !this.t) {
      this.t = this.x.redMul(this.y);
      if (!this.zOne)
        this.t = this.t.redMul(this.z.redInvm());
    }
  }
}
inherits(Point$2, base.BasePoint);

EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
  return Point$2.fromJSON(this, obj);
};

EdwardsCurve.prototype.point = function point(x, y, z, t) {
  return new Point$2(this, x, y, z, t);
};

Point$2.fromJSON = function fromJSON(curve, obj) {
  return new Point$2(curve, obj[0], obj[1], obj[2]);
};

Point$2.prototype.inspect = function inspect() {
  if (this.isInfinity())
    return '<EC Point Infinity>';
  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
      ' y: ' + this.y.fromRed().toString(16, 2) +
      ' z: ' + this.z.fromRed().toString(16, 2) + '>';
};

Point$2.prototype.isInfinity = function isInfinity() {
  // XXX This code assumes that zero is always zero in red
  return this.x.cmpn(0) === 0 &&
    (this.y.cmp(this.z) === 0 ||
    (this.zOne && this.y.cmp(this.curve.c) === 0));
};

Point$2.prototype._extDbl = function _extDbl() {
  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
  //     #doubling-dbl-2008-hwcd
  // 4M + 4S

  // A = X1^2
  var a = this.x.redSqr();
  // B = Y1^2
  var b = this.y.redSqr();
  // C = 2 * Z1^2
  var c = this.z.redSqr();
  c = c.redIAdd(c);
  // D = a * A
  var d = this.curve._mulA(a);
  // E = (X1 + Y1)^2 - A - B
  var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
  // G = D + B
  var g = d.redAdd(b);
  // F = G - C
  var f = g.redSub(c);
  // H = D - B
  var h = d.redSub(b);
  // X3 = E * F
  var nx = e.redMul(f);
  // Y3 = G * H
  var ny = g.redMul(h);
  // T3 = E * H
  var nt = e.redMul(h);
  // Z3 = F * G
  var nz = f.redMul(g);
  return this.curve.point(nx, ny, nz, nt);
};

Point$2.prototype._projDbl = function _projDbl() {
  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
  //     #doubling-dbl-2008-bbjlp
  //     #doubling-dbl-2007-bl
  // and others
  // Generally 3M + 4S or 2M + 4S

  // B = (X1 + Y1)^2
  var b = this.x.redAdd(this.y).redSqr();
  // C = X1^2
  var c = this.x.redSqr();
  // D = Y1^2
  var d = this.y.redSqr();

  var nx;
  var ny;
  var nz;
  if (this.curve.twisted) {
    // E = a * C
    var e = this.curve._mulA(c);
    // F = E + D
    var f = e.redAdd(d);
    if (this.zOne) {
      // X3 = (B - C - D) * (F - 2)
      nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
      // Y3 = F * (E - D)
      ny = f.redMul(e.redSub(d));
      // Z3 = F^2 - 2 * F
      nz = f.redSqr().redSub(f).redSub(f);
    } else {
      // H = Z1^2
      var h = this.z.redSqr();
      // J = F - 2 * H
      var j = f.redSub(h).redISub(h);
      // X3 = (B-C-D)*J
      nx = b.redSub(c).redISub(d).redMul(j);
      // Y3 = F * (E - D)
      ny = f.redMul(e.redSub(d));
      // Z3 = F * J
      nz = f.redMul(j);
    }
  } else {
    // E = C + D
    var e = c.redAdd(d);
    // H = (c * Z1)^2
    var h = this.curve._mulC(this.z).redSqr();
    // J = E - 2 * H
    var j = e.redSub(h).redSub(h);
    // X3 = c * (B - E) * J
    nx = this.curve._mulC(b.redISub(e)).redMul(j);
    // Y3 = c * E * (C - D)
    ny = this.curve._mulC(e).redMul(c.redISub(d));
    // Z3 = E * J
    nz = e.redMul(j);
  }
  return this.curve.point(nx, ny, nz);
};

Point$2.prototype.dbl = function dbl() {
  if (this.isInfinity())
    return this;

  // Double in extended coordinates
  if (this.curve.extended)
    return this._extDbl();
  else
    return this._projDbl();
};

Point$2.prototype._extAdd = function _extAdd(p) {
  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
  //     #addition-add-2008-hwcd-3
  // 8M

  // A = (Y1 - X1) * (Y2 - X2)
  var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
  // B = (Y1 + X1) * (Y2 + X2)
  var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
  // C = T1 * k * T2
  var c = this.t.redMul(this.curve.dd).redMul(p.t);
  // D = Z1 * 2 * Z2
  var d = this.z.redMul(p.z.redAdd(p.z));
  // E = B - A
  var e = b.redSub(a);
  // F = D - C
  var f = d.redSub(c);
  // G = D + C
  var g = d.redAdd(c);
  // H = B + A
  var h = b.redAdd(a);
  // X3 = E * F
  var nx = e.redMul(f);
  // Y3 = G * H
  var ny = g.redMul(h);
  // T3 = E * H
  var nt = e.redMul(h);
  // Z3 = F * G
  var nz = f.redMul(g);
  return this.curve.point(nx, ny, nz, nt);
};

Point$2.prototype._projAdd = function _projAdd(p) {
  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
  //     #addition-add-2008-bbjlp
  //     #addition-add-2007-bl
  // 10M + 1S

  // A = Z1 * Z2
  var a = this.z.redMul(p.z);
  // B = A^2
  var b = a.redSqr();
  // C = X1 * X2
  var c = this.x.redMul(p.x);
  // D = Y1 * Y2
  var d = this.y.redMul(p.y);
  // E = d * C * D
  var e = this.curve.d.redMul(c).redMul(d);
  // F = B - E
  var f = b.redSub(e);
  // G = B + E
  var g = b.redAdd(e);
  // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
  var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
  var nx = a.redMul(f).redMul(tmp);
  var ny;
  var nz;
  if (this.curve.twisted) {
    // Y3 = A * G * (D - a * C)
    ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
    // Z3 = F * G
    nz = f.redMul(g);
  } else {
    // Y3 = A * G * (D - C)
    ny = a.redMul(g).redMul(d.redSub(c));
    // Z3 = c * F * G
    nz = this.curve._mulC(f).redMul(g);
  }
  return this.curve.point(nx, ny, nz);
};

Point$2.prototype.add = function add(p) {
  if (this.isInfinity())
    return p;
  if (p.isInfinity())
    return this;

  if (this.curve.extended)
    return this._extAdd(p);
  else
    return this._projAdd(p);
};

Point$2.prototype.mul = function mul(k) {
  if (this._hasDoubles(k))
    return this.curve._fixedNafMul(this, k);
  else
    return this.curve._wnafMul(this, k);
};

Point$2.prototype.mulAdd = function mulAdd(k1, p, k2) {
  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
};

Point$2.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
};

Point$2.prototype.normalize = function normalize() {
  if (this.zOne)
    return this;

  // Normalize coordinates
  var zi = this.z.redInvm();
  this.x = this.x.redMul(zi);
  this.y = this.y.redMul(zi);
  if (this.t)
    this.t = this.t.redMul(zi);
  this.z = this.curve.one;
  this.zOne = true;
  return this;
};

Point$2.prototype.neg = function neg() {
  return this.curve.point(this.x.redNeg(),
                          this.y,
                          this.z,
                          this.t && this.t.redNeg());
};

Point$2.prototype.getX = function getX() {
  this.normalize();
  return this.x.fromRed();
};

Point$2.prototype.getY = function getY() {
  this.normalize();
  return this.y.fromRed();
};

Point$2.prototype.eq = function eq(other) {
  return this === other ||
         this.getX().cmp(other.getX()) === 0 &&
         this.getY().cmp(other.getY()) === 0;
};

Point$2.prototype.eqXToP = function eqXToP(x) {
  var rx = x.toRed(this.curve.red).redMul(this.z);
  if (this.x.cmp(rx) === 0)
    return true;

  var xc = x.clone();
  var t = this.curve.redN.redMul(this.z);
  for (;;) {
    xc.iadd(this.curve.n);
    if (xc.cmp(this.curve.p) >= 0)
      return false;

    rx.redIAdd(t);
    if (this.x.cmp(rx) === 0)
      return true;
  }
};

// Compatibility with BaseCurve
Point$2.prototype.toP = Point$2.prototype.normalize;
Point$2.prototype.mixedAdd = Point$2.prototype.add;

var curve_1 = createCommonjsModule(function (module, exports) {

var curve = exports;

curve.base = base;
curve.short = short_1;
curve.mont = mont;
curve.edwards = edwards;
});

var rotl32$2 = utils.rotl32;
var sum32$3 = utils.sum32;
var sum32_5$2 = utils.sum32_5;
var ft_1$1 = common$1.ft_1;
var BlockHash$4 = common.BlockHash;

var sha1_K = [
  0x5A827999, 0x6ED9EBA1,
  0x8F1BBCDC, 0xCA62C1D6
];

function SHA1() {
  if (!(this instanceof SHA1))
    return new SHA1();

  BlockHash$4.call(this);
  this.h = [
    0x67452301, 0xefcdab89, 0x98badcfe,
    0x10325476, 0xc3d2e1f0 ];
  this.W = new Array(80);
}

utils.inherits(SHA1, BlockHash$4);
var _1 = SHA1;

SHA1.blockSize = 512;
SHA1.outSize = 160;
SHA1.hmacStrength = 80;
SHA1.padLength = 64;

SHA1.prototype._update = function _update(msg, start) {
  var W = this.W;

  for (var i = 0; i < 16; i++)
    W[i] = msg[start + i];

  for(; i < W.length; i++)
    W[i] = rotl32$2(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);

  var a = this.h[0];
  var b = this.h[1];
  var c = this.h[2];
  var d = this.h[3];
  var e = this.h[4];

  for (i = 0; i < W.length; i++) {
    var s = ~~(i / 20);
    var t = sum32_5$2(rotl32$2(a, 5), ft_1$1(s, b, c, d), e, W[i], sha1_K[s]);
    e = d;
    d = c;
    c = rotl32$2(b, 30);
    b = a;
    a = t;
  }

  this.h[0] = sum32$3(this.h[0], a);
  this.h[1] = sum32$3(this.h[1], b);
  this.h[2] = sum32$3(this.h[2], c);
  this.h[3] = sum32$3(this.h[3], d);
  this.h[4] = sum32$3(this.h[4], e);
};

SHA1.prototype._digest = function digest(enc) {
  if (enc === 'hex')
    return utils.toHex32(this.h, 'big');
  else
    return utils.split32(this.h, 'big');
};

var sha1 = _1;
var sha224 = _224;
var sha256 = _256;
var sha384 = _384;
var sha512 = _512;

var sha = {
	sha1: sha1,
	sha224: sha224,
	sha256: sha256,
	sha384: sha384,
	sha512: sha512
};

function Hmac(hash, key, enc) {
  if (!(this instanceof Hmac))
    return new Hmac(hash, key, enc);
  this.Hash = hash;
  this.blockSize = hash.blockSize / 8;
  this.outSize = hash.outSize / 8;
  this.inner = null;
  this.outer = null;

  this._init(utils.toArray(key, enc));
}
var hmac = Hmac;

Hmac.prototype._init = function init(key) {
  // Shorten key, if needed
  if (key.length > this.blockSize)
    key = new this.Hash().update(key).digest();
  minimalisticAssert(key.length <= this.blockSize);

  // Add padding to key
  for (var i = key.length; i < this.blockSize; i++)
    key.push(0);

  for (i = 0; i < key.length; i++)
    key[i] ^= 0x36;
  this.inner = new this.Hash().update(key);

  // 0x36 ^ 0x5c = 0x6a
  for (i = 0; i < key.length; i++)
    key[i] ^= 0x6a;
  this.outer = new this.Hash().update(key);
};

Hmac.prototype.update = function update(msg, enc) {
  this.inner.update(msg, enc);
  return this;
};

Hmac.prototype.digest = function digest(enc) {
  this.outer.update(this.inner.digest());
  return this.outer.digest(enc);
};

var hash_1 = createCommonjsModule(function (module, exports) {
var hash = exports;

hash.utils = utils;
hash.common = common;
hash.sha = sha;
hash.ripemd = ripemd;
hash.hmac = hmac;

// Proxy hash functions to the main object
hash.sha1 = hash.sha.sha1;
hash.sha256 = hash.sha.sha256;
hash.sha224 = hash.sha.sha224;
hash.sha384 = hash.sha.sha384;
hash.sha512 = hash.sha.sha512;
hash.ripemd160 = hash.ripemd.ripemd160;
});

var secp256k1 = {
  doubles: {
    step: 4,
    points: [
      [
        'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
        'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
      ],
      [
        '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
        '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
      ],
      [
        '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
        'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
      ],
      [
        '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
        '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
      ],
      [
        '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
        '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
      ],
      [
        '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
        '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
      ],
      [
        'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
        '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
      ],
      [
        '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
        'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
      ],
      [
        'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
        '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
      ],
      [
        'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
        'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
      ],
      [
        'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
        '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
      ],
      [
        '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
        '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
      ],
      [
        '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
        '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
      ],
      [
        '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
        '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
      ],
      [
        '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
        '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
      ],
      [
        '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
        '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
      ],
      [
        '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
        '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
      ],
      [
        '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
        '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
      ],
      [
        '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
        'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
      ],
      [
        'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
        '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
      ],
      [
        'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
        '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
      ],
      [
        '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
        '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
      ],
      [
        '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
        '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
      ],
      [
        'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
        '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
      ],
      [
        '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
        'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
      ],
      [
        'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
        '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
      ],
      [
        'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
        'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
      ],
      [
        'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
        '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
      ],
      [
        'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
        'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
      ],
      [
        'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
        '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
      ],
      [
        '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
        'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
      ],
      [
        '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
        '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
      ],
      [
        'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
        '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
      ],
      [
        '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
        'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
      ],
      [
        'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
        '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
      ],
      [
        'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
        '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
      ],
      [
        'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
        'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
      ],
      [
        '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
        '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
      ],
      [
        '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
        '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
      ],
      [
        '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
        'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
      ],
      [
        '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
        '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
      ],
      [
        'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
        '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
      ],
      [
        '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
        '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
      ],
      [
        '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
        'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
      ],
      [
        '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
        '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
      ],
      [
        'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
        '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
      ],
      [
        '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
        'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
      ],
      [
        'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
        'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
      ],
      [
        'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
        '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
      ],
      [
        '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
        'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
      ],
      [
        '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
        'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
      ],
      [
        'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
        '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
      ],
      [
        'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
        '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
      ],
      [
        'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
        '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
      ],
      [
        '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
        'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
      ],
      [
        '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
        '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
      ],
      [
        'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
        'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
      ],
      [
        '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
        'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
      ],
      [
        '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
        '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
      ],
      [
        '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
        '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
      ],
      [
        'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
        'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
      ],
      [
        '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
        '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
      ],
      [
        '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
        '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
      ],
      [
        'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
        '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
      ],
      [
        'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
        'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
      ]
    ]
  },
  naf: {
    wnd: 7,
    points: [
      [
        'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
        '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
      ],
      [
        '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
        'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
      ],
      [
        '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
        '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
      ],
      [
        'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
        'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
      ],
      [
        '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
        'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
      ],
      [
        'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
        'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
      ],
      [
        'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
        '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
      ],
      [
        'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
        '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
      ],
      [
        '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
        '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
      ],
      [
        '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
        '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
      ],
      [
        '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
        '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
      ],
      [
        '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
        '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
      ],
      [
        'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
        'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
      ],
      [
        'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
        '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
      ],
      [
        '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
        'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
      ],
      [
        '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
        'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
      ],
      [
        '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
        '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
      ],
      [
        '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
        '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
      ],
      [
        '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
        '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
      ],
      [
        '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
        'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
      ],
      [
        'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
        'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
      ],
      [
        '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
        '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
      ],
      [
        '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
        '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
      ],
      [
        'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
        'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
      ],
      [
        '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
        '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
      ],
      [
        'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
        'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
      ],
      [
        'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
        'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
      ],
      [
        '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
        '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
      ],
      [
        '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
        '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
      ],
      [
        '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
        '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
      ],
      [
        'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
        '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
      ],
      [
        '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
        '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
      ],
      [
        'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
        '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
      ],
      [
        '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
        'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
      ],
      [
        '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
        'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
      ],
      [
        'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
        'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
      ],
      [
        '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
        '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
      ],
      [
        '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
        'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
      ],
      [
        'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
        'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
      ],
      [
        '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
        '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
      ],
      [
        '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
        'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
      ],
      [
        '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
        '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
      ],
      [
        '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
        'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
      ],
      [
        'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
        '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
      ],
      [
        '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
        '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
      ],
      [
        '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
        'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
      ],
      [
        '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
        'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
      ],
      [
        'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
        'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
      ],
      [
        'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
        'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
      ],
      [
        '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
        '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
      ],
      [
        '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
        '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
      ],
      [
        'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
        '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
      ],
      [
        'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
        'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
      ],
      [
        '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
        '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
      ],
      [
        '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
        '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
      ],
      [
        'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
        '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
      ],
      [
        '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
        '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
      ],
      [
        'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
        'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
      ],
      [
        '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
        'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
      ],
      [
        '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
        '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
      ],
      [
        'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
        '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
      ],
      [
        'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
        '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
      ],
      [
        '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
        '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
      ],
      [
        '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
        '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
      ],
      [
        '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
        'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
      ],
      [
        '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
        'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
      ],
      [
        '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
        '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
      ],
      [
        '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
        '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
      ],
      [
        '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
        '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
      ],
      [
        '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
        'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
      ],
      [
        'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
        'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
      ],
      [
        '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
        'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
      ],
      [
        'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
        '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
      ],
      [
        'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
        '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
      ],
      [
        'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
        '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
      ],
      [
        'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
        '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
      ],
      [
        '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
        'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
      ],
      [
        '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
        '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
      ],
      [
        '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
        'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
      ],
      [
        'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
        'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
      ],
      [
        'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
        '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
      ],
      [
        'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
        'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
      ],
      [
        'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
        '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
      ],
      [
        '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
        '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
      ],
      [
        'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
        '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
      ],
      [
        'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
        '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
      ],
      [
        '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
        '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
      ],
      [
        '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
        'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
      ],
      [
        'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
        '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
      ],
      [
        'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
        '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
      ],
      [
        'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
        '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
      ],
      [
        '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
        '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
      ],
      [
        'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
        'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
      ],
      [
        '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
        'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
      ],
      [
        'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
        'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
      ],
      [
        'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
        '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
      ],
      [
        '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
        'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
      ],
      [
        'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
        '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
      ],
      [
        'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
        '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
      ],
      [
        'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
        '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
      ],
      [
        '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
        'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
      ],
      [
        '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
        'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
      ],
      [
        'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
        '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
      ],
      [
        '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
        'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
      ],
      [
        '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
        '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
      ],
      [
        '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
        'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
      ],
      [
        'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
        'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
      ],
      [
        '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
        'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
      ],
      [
        '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
        '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
      ],
      [
        '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
        'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
      ],
      [
        '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
        '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
      ],
      [
        'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
        'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
      ],
      [
        '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
        '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
      ],
      [
        'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
        '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
      ],
      [
        '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
        '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
      ],
      [
        'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
        'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
      ],
      [
        'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
        '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
      ],
      [
        'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
        'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
      ],
      [
        '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
        'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
      ],
      [
        '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
        '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
      ],
      [
        '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
        'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
      ],
      [
        '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
        '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
      ],
      [
        '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
        '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
      ],
      [
        '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
        'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
      ],
      [
        '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
        '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
      ],
      [
        '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
        '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
      ],
      [
        '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
        '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
      ]
    ]
  }
};

var curves_1 = createCommonjsModule(function (module, exports) {

var curves = exports;





var assert = utils_1$1.assert;

function PresetCurve(options) {
  if (options.type === 'short')
    this.curve = new curve_1.short(options);
  else if (options.type === 'edwards')
    this.curve = new curve_1.edwards(options);
  else if (options.type === 'mont')
    this.curve = new curve_1.mont(options);
  else throw new Error('Unknown curve type.');
  this.g = this.curve.g;
  this.n = this.curve.n;
  this.hash = options.hash;

  assert(this.g.validate(), 'Invalid curve');
  assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, n*G != O');
}
curves.PresetCurve = PresetCurve;

function defineCurve(name, options) {
  Object.defineProperty(curves, name, {
    configurable: true,
    enumerable: true,
    get: function() {
      var curve = new PresetCurve(options);
      Object.defineProperty(curves, name, {
        configurable: true,
        enumerable: true,
        value: curve
      });
      return curve;
    }
  });
}

defineCurve('p192', {
  type: 'short',
  prime: 'p192',
  p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
  b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
  n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
  hash: hash_1.sha256,
  gRed: false,
  g: [
    '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
    '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
  ]
});

defineCurve('p224', {
  type: 'short',
  prime: 'p224',
  p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
  b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
  n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
  hash: hash_1.sha256,
  gRed: false,
  g: [
    'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
    'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
  ]
});

defineCurve('p256', {
  type: 'short',
  prime: null,
  p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
  a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
  b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
  n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
  hash: hash_1.sha256,
  gRed: false,
  g: [
    '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
    '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
  ]
});

defineCurve('p384', {
  type: 'short',
  prime: null,
  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
     'fffffffe ffffffff 00000000 00000000 ffffffff',
  a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
     'fffffffe ffffffff 00000000 00000000 fffffffc',
  b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
     '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
  n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
     'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
  hash: hash_1.sha384,
  gRed: false,
  g: [
    'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
    '5502f25d bf55296c 3a545e38 72760ab7',
    '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
    '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
  ]
});

defineCurve('p521', {
  type: 'short',
  prime: null,
  p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
     'ffffffff ffffffff ffffffff ffffffff ffffffff',
  a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
     'ffffffff ffffffff ffffffff ffffffff fffffffc',
  b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
     '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
     '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
  n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
     'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
     'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
  hash: hash_1.sha512,
  gRed: false,
  g: [
    '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
    '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
    'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
    '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
    '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
    '3fad0761 353c7086 a272c240 88be9476 9fd16650'
  ]
});

// https://tools.ietf.org/html/rfc7748#section-4.1
defineCurve('curve25519', {
  type: 'mont',
  prime: 'p25519',
  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
  a: '76d06',
  b: '1',
  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
  cofactor: '8',
  hash: hash_1.sha256,
  gRed: false,
  g: [
    '9'
  ]
});

defineCurve('ed25519', {
  type: 'edwards',
  prime: 'p25519',
  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
  a: '-1',
  c: '1',
  // -121665 * (121666^(-1)) (mod P)
  d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
  cofactor: '8',
  hash: hash_1.sha256,
  gRed: false,
  g: [
    '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
    // 4/5
    '6666666666666666666666666666666666666666666666666666666666666658'
  ]
});

// https://tools.ietf.org/html/rfc5639#section-3.4
defineCurve('brainpoolP256r1', {
  type: 'short',
  prime: null,
  p: 'A9FB57DB A1EEA9BC 3E660A90 9D838D72 6E3BF623 D5262028 2013481D 1F6E5377',
  a: '7D5A0975 FC2C3057 EEF67530 417AFFE7 FB8055C1 26DC5C6C E94A4B44 F330B5D9',
  b: '26DC5C6C E94A4B44 F330B5D9 BBD77CBF 95841629 5CF7E1CE 6BCCDC18 FF8C07B6',
  n: 'A9FB57DB A1EEA9BC 3E660A90 9D838D71 8C397AA3 B561A6F7 901E0E82 974856A7',
  hash: hash_1.sha256, // or 384, or 512
  gRed: false,
  g: [
    '8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262',
    '547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997'
  ]
});

// https://tools.ietf.org/html/rfc5639#section-3.6
defineCurve('brainpoolP384r1', {
  type: 'short',
  prime: null,
  p: '8CB91E82 A3386D28 0F5D6F7E 50E641DF 152F7109 ED5456B4 12B1DA19 7FB71123' +
    'ACD3A729 901D1A71 87470013 3107EC53',
  a: '7BC382C6 3D8C150C 3C72080A CE05AFA0 C2BEA28E 4FB22787 139165EF BA91F90F' +
    '8AA5814A 503AD4EB 04A8C7DD 22CE2826',
  b: '04A8C7DD 22CE2826 8B39B554 16F0447C 2FB77DE1 07DCD2A6 2E880EA5 3EEB62D5' +
    '7CB43902 95DBC994 3AB78696 FA504C11',
  n: '8CB91E82 A3386D28 0F5D6F7E 50E641DF 152F7109 ED5456B3 1F166E6C AC0425A7' +
    'CF3AB6AF 6B7FC310 3B883202 E9046565',
  hash: hash_1.sha384, // or 512
  gRed: false,
  g: [
    '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10' +
      'E8E826E03436D646AAEF87B2E247D4AF1E',
    '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129' +
      '280E4646217791811142820341263C5315'
  ]
});

// https://tools.ietf.org/html/rfc5639#section-3.7
defineCurve('brainpoolP512r1', {
  type: 'short',
  prime: null,
  p: 'AADD9DB8 DBE9C48B 3FD4E6AE 33C9FC07 CB308DB3 B3C9D20E D6639CCA 70330871' +
    '7D4D9B00 9BC66842 AECDA12A E6A380E6 2881FF2F 2D82C685 28AA6056 583A48F3',
  a: '7830A331 8B603B89 E2327145 AC234CC5 94CBDD8D 3DF91610 A83441CA EA9863BC' +
    '2DED5D5A A8253AA1 0A2EF1C9 8B9AC8B5 7F1117A7 2BF2C7B9 E7C1AC4D 77FC94CA',
  b: '3DF91610 A83441CA EA9863BC 2DED5D5A A8253AA1 0A2EF1C9 8B9AC8B5 7F1117A7' +
    '2BF2C7B9 E7C1AC4D 77FC94CA DC083E67 984050B7 5EBAE5DD 2809BD63 8016F723',
  n: 'AADD9DB8 DBE9C48B 3FD4E6AE 33C9FC07 CB308DB3 B3C9D20E D6639CCA 70330870' +
    '553E5C41 4CA92619 41866119 7FAC1047 1DB1D381 085DDADD B5879682 9CA90069',
  hash: hash_1.sha512,
  gRed: false,
  g: [
    '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009' +
      '8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822',
    '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81' +
      '11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892'
  ]
});

// https://en.bitcoin.it/wiki/Secp256k1
var pre;
try {
  pre = secp256k1;
} catch (e) {
  pre = undefined;
}

defineCurve('secp256k1', {
  type: 'short',
  prime: 'k256',
  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
  a: '0',
  b: '7',
  n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
  h: '1',
  hash: hash_1.sha256,

  // Precomputed endomorphism
  beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
  lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
  basis: [
    {
      a: '3086d221a7d46bcde86c90e49284eb15',
      b: '-e4437ed6010e88286f547fa90abfe4c3'
    },
    {
      a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
      b: '3086d221a7d46bcde86c90e49284eb15'
    }
  ],

  gRed: false,
  g: [
    '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
    '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
    pre
  ]
});
});

function HmacDRBG(options) {
  if (!(this instanceof HmacDRBG))
    return new HmacDRBG(options);
  this.hash = options.hash;
  this.predResist = !!options.predResist;

  this.outLen = this.hash.outSize;
  this.minEntropy = options.minEntropy || this.hash.hmacStrength;

  this._reseed = null;
  this.reseedInterval = null;
  this.K = null;
  this.V = null;

  var entropy = utils_1.toArray(options.entropy, options.entropyEnc || 'hex');
  var nonce = utils_1.toArray(options.nonce, options.nonceEnc || 'hex');
  var pers = utils_1.toArray(options.pers, options.persEnc || 'hex');
  minimalisticAssert(entropy.length >= (this.minEntropy / 8),
         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
  this._init(entropy, nonce, pers);
}
var hmacDrbg = HmacDRBG;

HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
  var seed = entropy.concat(nonce).concat(pers);

  this.K = new Array(this.outLen / 8);
  this.V = new Array(this.outLen / 8);
  for (var i = 0; i < this.V.length; i++) {
    this.K[i] = 0x00;
    this.V[i] = 0x01;
  }

  this._update(seed);
  this._reseed = 1;
  this.reseedInterval = 0x1000000000000;  // 2^48
};

HmacDRBG.prototype._hmac = function hmac() {
  return new hash_1.hmac(this.hash, this.K);
};

HmacDRBG.prototype._update = function update(seed) {
  var kmac = this._hmac()
                 .update(this.V)
                 .update([ 0x00 ]);
  if (seed)
    kmac = kmac.update(seed);
  this.K = kmac.digest();
  this.V = this._hmac().update(this.V).digest();
  if (!seed)
    return;

  this.K = this._hmac()
               .update(this.V)
               .update([ 0x01 ])
               .update(seed)
               .digest();
  this.V = this._hmac().update(this.V).digest();
};

HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
  // Optional entropy enc
  if (typeof entropyEnc !== 'string') {
    addEnc = add;
    add = entropyEnc;
    entropyEnc = null;
  }

  entropy = utils_1.toArray(entropy, entropyEnc);
  add = utils_1.toArray(add, addEnc);

  minimalisticAssert(entropy.length >= (this.minEntropy / 8),
         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');

  this._update(entropy.concat(add || []));
  this._reseed = 1;
};

HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
  if (this._reseed > this.reseedInterval)
    throw new Error('Reseed is required');

  // Optional encoding
  if (typeof enc !== 'string') {
    addEnc = add;
    add = enc;
    enc = null;
  }

  // Optional additional data
  if (add) {
    add = utils_1.toArray(add, addEnc || 'hex');
    this._update(add);
  }

  var temp = [];
  while (temp.length < len) {
    this.V = this._hmac().update(this.V).digest();
    temp = temp.concat(this.V);
  }

  var res = temp.slice(0, len);
  this._update(add);
  this._reseed++;
  return utils_1.encode(res, enc);
};

var assert$5 = utils_1$1.assert;

function KeyPair(ec, options) {
  this.ec = ec;
  this.priv = null;
  this.pub = null;

  // KeyPair(ec, { priv: ..., pub: ... })
  if (options.priv)
    this._importPrivate(options.priv, options.privEnc);
  if (options.pub)
    this._importPublic(options.pub, options.pubEnc);
}
var key = KeyPair;

KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
  if (pub instanceof KeyPair)
    return pub;

  return new KeyPair(ec, {
    pub: pub,
    pubEnc: enc
  });
};

KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
  if (priv instanceof KeyPair)
    return priv;

  return new KeyPair(ec, {
    priv: priv,
    privEnc: enc
  });
};

// TODO: should not validate for X25519
KeyPair.prototype.validate = function validate() {
  var pub = this.getPublic();

  if (pub.isInfinity())
    return { result: false, reason: 'Invalid public key' };
  if (!pub.validate())
    return { result: false, reason: 'Public key is not a point' };
  if (!pub.mul(this.ec.curve.n).isInfinity())
    return { result: false, reason: 'Public key * N != O' };

  return { result: true, reason: null };
};

KeyPair.prototype.getPublic = function getPublic(enc, compact) {
  if (!this.pub)
    this.pub = this.ec.g.mul(this.priv);

  if (!enc)
    return this.pub;

  return this.pub.encode(enc, compact);
};

KeyPair.prototype.getPrivate = function getPrivate(enc) {
  if (enc === 'hex')
    return this.priv.toString(16, 2);
  else
    return this.priv;
};

KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
  this.priv = new bn(key, enc || 16);

  // For Curve25519/Curve448 we have a specific procedure.
  // TODO Curve448
  if (this.ec.curve.type === 'mont') {
    var one = this.ec.curve.one;
    var mask = one.ushln(255 - 3).sub(one).ushln(3);
    this.priv = this.priv.or(one.ushln(255 - 1));
    this.priv = this.priv.and(mask);
  } else
    // Ensure that the priv won't be bigger than n, otherwise we may fail
    // in fixed multiplication method
    this.priv = this.priv.umod(this.ec.curve.n);
};

KeyPair.prototype._importPublic = function _importPublic(key, enc) {
  if (key.x || key.y) {
    // Montgomery points only have an `x` coordinate.
    // Weierstrass/Edwards points on the other hand have both `x` and
    // `y` coordinates.
    if (this.ec.curve.type === 'mont') {
      assert$5(key.x, 'Need x coordinate');
    } else if (this.ec.curve.type === 'short' ||
               this.ec.curve.type === 'edwards') {
      assert$5(key.x && key.y, 'Need both x and y coordinate');
    }
    this.pub = this.ec.curve.point(key.x, key.y);
    return;
  }
  this.pub = this.ec.curve.decodePoint(key, enc);
};

// ECDH
KeyPair.prototype.derive = function derive(pub) {
  return pub.mul(this.priv).getX();
};

// ECDSA
KeyPair.prototype.sign = function sign(msg, enc, options) {
  return this.ec.sign(msg, this, enc, options);
};

KeyPair.prototype.verify = function verify(msg, signature) {
  return this.ec.verify(msg, signature, this);
};

KeyPair.prototype.inspect = function inspect() {
  return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
         ' pub: ' + (this.pub && this.pub.inspect()) + ' >';
};

var assert$6 = utils_1$1.assert;

function Signature$1(options, enc) {
  if (options instanceof Signature$1)
    return options;

  if (this._importDER(options, enc))
    return;

  assert$6(options.r && options.s, 'Signature without r or s');
  this.r = new bn(options.r, 16);
  this.s = new bn(options.s, 16);
  if (options.recoveryParam === undefined)
    this.recoveryParam = null;
  else
    this.recoveryParam = options.recoveryParam;
}
var signature$1 = Signature$1;

function Position() {
  this.place = 0;
}

function getLength(buf, p) {
  var initial = buf[p.place++];
  if (!(initial & 0x80)) {
    return initial;
  }
  var octetLen = initial & 0xf;
  var val = 0;
  for (var i = 0, off = p.place; i < octetLen; i++, off++) {
    val <<= 8;
    val |= buf[off];
  }
  p.place = off;
  return val;
}

function rmPadding(buf) {
  var i = 0;
  var len = buf.length - 1;
  while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
    i++;
  }
  if (i === 0) {
    return buf;
  }
  return buf.slice(i);
}

Signature$1.prototype._importDER = function _importDER(data, enc) {
  data = utils_1$1.toArray(data, enc);
  var p = new Position();
  if (data[p.place++] !== 0x30) {
    return false;
  }
  var len = getLength(data, p);
  if ((len + p.place) !== data.length) {
    return false;
  }
  if (data[p.place++] !== 0x02) {
    return false;
  }
  var rlen = getLength(data, p);
  var r = data.slice(p.place, rlen + p.place);
  p.place += rlen;
  if (data[p.place++] !== 0x02) {
    return false;
  }
  var slen = getLength(data, p);
  if (data.length !== slen + p.place) {
    return false;
  }
  var s = data.slice(p.place, slen + p.place);
  if (r[0] === 0 && (r[1] & 0x80)) {
    r = r.slice(1);
  }
  if (s[0] === 0 && (s[1] & 0x80)) {
    s = s.slice(1);
  }

  this.r = new bn(r);
  this.s = new bn(s);
  this.recoveryParam = null;

  return true;
};

function constructLength(arr, len) {
  if (len < 0x80) {
    arr.push(len);
    return;
  }
  var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
  arr.push(octets | 0x80);
  while (--octets) {
    arr.push((len >>> (octets << 3)) & 0xff);
  }
  arr.push(len);
}

Signature$1.prototype.toDER = function toDER(enc) {
  var r = this.r.toArray();
  var s = this.s.toArray();

  // Pad values
  if (r[0] & 0x80)
    r = [ 0 ].concat(r);
  // Pad values
  if (s[0] & 0x80)
    s = [ 0 ].concat(s);

  r = rmPadding(r);
  s = rmPadding(s);

  while (!s[0] && !(s[1] & 0x80)) {
    s = s.slice(1);
  }
  var arr = [ 0x02 ];
  constructLength(arr, r.length);
  arr = arr.concat(r);
  arr.push(0x02);
  constructLength(arr, s.length);
  var backHalf = arr.concat(s);
  var res = [ 0x30 ];
  constructLength(res, backHalf.length);
  res = res.concat(backHalf);
  return utils_1$1.encode(res, enc);
};

var assert$7 = utils_1$1.assert;




function EC(options) {
  if (!(this instanceof EC))
    return new EC(options);

  // Shortcut `elliptic.ec(curve-name)`
  if (typeof options === 'string') {
    assert$7(curves_1.hasOwnProperty(options), 'Unknown curve ' + options);

    options = curves_1[options];
  }

  // Shortcut for `elliptic.ec(elliptic.curves.curveName)`
  if (options instanceof curves_1.PresetCurve)
    options = { curve: options };

  this.curve = options.curve.curve;
  this.n = this.curve.n;
  this.nh = this.n.ushrn(1);
  this.g = this.curve.g;

  // Point on curve
  this.g = options.curve.g;
  this.g.precompute(options.curve.n.bitLength() + 1);

  // Hash function for DRBG
  this.hash = options.hash || options.curve.hash;
}
var ec = EC;

EC.prototype.keyPair = function keyPair(options) {
  return new key(this, options);
};

EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
  return key.fromPrivate(this, priv, enc);
};

EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
  return key.fromPublic(this, pub, enc);
};

EC.prototype.genKeyPair = function genKeyPair(options) {
  if (!options)
    options = {};

  // Instantiate Hmac_DRBG
  var drbg = new hmacDrbg({
    hash: this.hash,
    pers: options.pers,
    persEnc: options.persEnc || 'utf8',
    entropy: options.entropy || brorand(this.hash.hmacStrength),
    entropyEnc: options.entropy && options.entropyEnc || 'utf8',
    nonce: this.n.toArray()
  });

  // Key generation for curve25519 is simpler
  if (this.curve.type === 'mont') {
    var priv = new bn(drbg.generate(32));
    return this.keyFromPrivate(priv);
  }

  var bytes = this.n.byteLength();
  var ns2 = this.n.sub(new bn(2));
  do {
    var priv = new bn(drbg.generate(bytes));
    if (priv.cmp(ns2) > 0)
      continue;

    priv.iaddn(1);
    return this.keyFromPrivate(priv);
  } while (true);
};

EC.prototype._truncateToN = function truncateToN(msg, truncOnly, bitSize) {
  bitSize = bitSize || msg.byteLength() * 8;
  var delta = bitSize - this.n.bitLength();
  if (delta > 0)
    msg = msg.ushrn(delta);
  if (!truncOnly && msg.cmp(this.n) >= 0)
    return msg.sub(this.n);
  else
    return msg;
};

EC.prototype.truncateMsg  = function truncateMSG(msg) {
  // Bit size is only determined correctly for Uint8Arrays and hex strings
  var bitSize;
  if (msg instanceof Uint8Array) {
    bitSize = msg.byteLength * 8;
    msg = this._truncateToN(new bn(msg, 16), false, bitSize);
  } else if (typeof msg === 'string') {
    bitSize = msg.length * 4;
    msg = this._truncateToN(new bn(msg, 16), false, bitSize);
  } else {
    msg = this._truncateToN(new bn(msg, 16));
  }
  return msg;
};

EC.prototype.sign = function sign(msg, key, enc, options) {
  if (typeof enc === 'object') {
    options = enc;
    enc = null;
  }
  if (!options)
    options = {};

  key = this.keyFromPrivate(key, enc);
  msg = this.truncateMsg(msg);

  // Zero-extend key to provide enough entropy
  var bytes = this.n.byteLength();
  var bkey = key.getPrivate().toArray('be', bytes);

  // Zero-extend nonce to have the same byte size as N
  var nonce = msg.toArray('be', bytes);

  // Instantiate Hmac_DRBG
  var drbg = new hmacDrbg({
    hash: this.hash,
    entropy: bkey,
    nonce: nonce,
    pers: options.pers,
    persEnc: options.persEnc || 'utf8'
  });

  // Number of bytes to generate
  var ns1 = this.n.sub(new bn(1));

  for (var iter = 0; true; iter++) {
    var k = options.k ?
        options.k(iter) :
        new bn(drbg.generate(this.n.byteLength()));
    k = this._truncateToN(k, true);
    if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
      continue;

    var kp = this.g.mul(k);
    if (kp.isInfinity())
      continue;

    var kpX = kp.getX();
    var r = kpX.umod(this.n);
    if (r.cmpn(0) === 0)
      continue;

    var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
    s = s.umod(this.n);
    if (s.cmpn(0) === 0)
      continue;

    var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
                        (kpX.cmp(r) !== 0 ? 2 : 0);

    // Use complement of `s`, if it is > `n / 2`
    if (options.canonical && s.cmp(this.nh) > 0) {
      s = this.n.sub(s);
      recoveryParam ^= 1;
    }

    return new signature$1({ r: r, s: s, recoveryParam: recoveryParam });
  }
};

EC.prototype.verify = function verify(msg, signature, key, enc) {
  key = this.keyFromPublic(key, enc);
  signature = new signature$1(signature, 'hex');
  // Fallback to the old code
  var ret = this._verify(this.truncateMsg(msg), signature, key) ||
  this._verify(this._truncateToN(new bn(msg, 16)), signature, key);
  return ret;
};

EC.prototype._verify = function _verify(msg, signature, key) {
  // Perform primitive values validation
  var r = signature.r;
  var s = signature.s;
  if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
    return false;
  if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
    return false;

  // Validate signature
  var sinv = s.invm(this.n);
  var u1 = sinv.mul(msg).umod(this.n);
  var u2 = sinv.mul(r).umod(this.n);

  if (!this.curve._maxwellTrick) {
    var p = this.g.mulAdd(u1, key.getPublic(), u2);
    if (p.isInfinity())
      return false;

    return p.getX().umod(this.n).cmp(r) === 0;
  }

  // NOTE: Greg Maxwell's trick, inspired by:
  // https://git.io/vad3K

  var p = this.g.jmulAdd(u1, key.getPublic(), u2);
  if (p.isInfinity())
    return false;

  // Compare `p.x` of Jacobian point with `r`,
  // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
  // inverse of `p.z^2`
  return p.eqXToP(r);
};

EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
  assert$7((3 & j) === j, 'The recovery param is more than two bits');
  signature = new signature$1(signature, enc);

  var n = this.n;
  var e = new bn(msg);
  var r = signature.r;
  var s = signature.s;

  // A set LSB signifies that the y-coordinate is odd
  var isYOdd = j & 1;
  var isSecondKey = j >> 1;
  if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
    throw new Error('Unable to find sencond key candinate');

  // 1.1. Let x = r + jn.
  if (isSecondKey)
    r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
  else
    r = this.curve.pointFromX(r, isYOdd);

  var rInv = signature.r.invm(n);
  var s1 = n.sub(e).mul(rInv).umod(n);
  var s2 = s.mul(rInv).umod(n);

  // 1.6.1 Compute Q = r^-1 (sR -  eG)
  //               Q = r^-1 (sR + -eG)
  return this.g.mulAdd(s1, r, s2);
};

EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
  signature = new signature$1(signature, enc);
  if (signature.recoveryParam !== null)
    return signature.recoveryParam;

  for (var i = 0; i < 4; i++) {
    var Qprime;
    try {
      Qprime = this.recoverPubKey(e, signature, i);
    } catch (e) {
      continue;
    }

    if (Qprime.eq(Q))
      return i;
  }
  throw new Error('Unable to find valid recovery factor');
};

var assert$8 = utils_1$1.assert;
var parseBytes = utils_1$1.parseBytes;
var cachedProperty = utils_1$1.cachedProperty;

/**
* @param {EDDSA} eddsa - instance
* @param {Object} params - public/private key parameters
*
* @param {Array<Byte>} [params.secret] - secret seed bytes
* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
*
*/
function KeyPair$1(eddsa, params) {
  this.eddsa = eddsa;
  if (params.hasOwnProperty('secret'))
    this._secret = parseBytes(params.secret);
  if (eddsa.isPoint(params.pub))
    this._pub = params.pub;
  else {
    this._pubBytes = parseBytes(params.pub);
    if (this._pubBytes && this._pubBytes.length === 33 &&
        this._pubBytes[0] === 0x40)
      this._pubBytes = this._pubBytes.slice(1, 33);
    if (this._pubBytes && this._pubBytes.length !== 32)
      throw new Error('Unknown point compression format');
  }
}

KeyPair$1.fromPublic = function fromPublic(eddsa, pub) {
  if (pub instanceof KeyPair$1)
    return pub;
  return new KeyPair$1(eddsa, { pub: pub });
};

KeyPair$1.fromSecret = function fromSecret(eddsa, secret) {
  if (secret instanceof KeyPair$1)
    return secret;
  return new KeyPair$1(eddsa, { secret: secret });
};

KeyPair$1.prototype.secret = function secret() {
  return this._secret;
};

cachedProperty(KeyPair$1, 'pubBytes', function pubBytes() {
  return this.eddsa.encodePoint(this.pub());
});

cachedProperty(KeyPair$1, 'pub', function pub() {
  if (this._pubBytes)
    return this.eddsa.decodePoint(this._pubBytes);
  return this.eddsa.g.mul(this.priv());
});

cachedProperty(KeyPair$1, 'privBytes', function privBytes() {
  var eddsa = this.eddsa;
  var hash = this.hash();
  var lastIx = eddsa.encodingLength - 1;

  // https://tools.ietf.org/html/rfc8032#section-5.1.5
  var a = hash.slice(0, eddsa.encodingLength);
  a[0] &= 248;
  a[lastIx] &= 127;
  a[lastIx] |= 64;

  return a;
});

cachedProperty(KeyPair$1, 'priv', function priv() {
  return this.eddsa.decodeInt(this.privBytes());
});

cachedProperty(KeyPair$1, 'hash', function hash() {
  return this.eddsa.hash().update(this.secret()).digest();
});

cachedProperty(KeyPair$1, 'messagePrefix', function messagePrefix() {
  return this.hash().slice(this.eddsa.encodingLength);
});

KeyPair$1.prototype.sign = function sign(message) {
  assert$8(this._secret, 'KeyPair can only verify');
  return this.eddsa.sign(message, this);
};

KeyPair$1.prototype.verify = function verify(message, sig) {
  return this.eddsa.verify(message, sig, this);
};

KeyPair$1.prototype.getSecret = function getSecret(enc) {
  assert$8(this._secret, 'KeyPair is public only');
  return utils_1$1.encode(this.secret(), enc);
};

KeyPair$1.prototype.getPublic = function getPublic(enc, compact) {
  return utils_1$1.encode((compact ? [ 0x40 ] : []).concat(this.pubBytes()), enc);
};

var key$1 = KeyPair$1;

var assert$9 = utils_1$1.assert;
var cachedProperty$1 = utils_1$1.cachedProperty;
var parseBytes$1 = utils_1$1.parseBytes;

/**
* @param {EDDSA} eddsa - eddsa instance
* @param {Array<Bytes>|Object} sig -
* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
*/
function Signature$2(eddsa, sig) {
  this.eddsa = eddsa;

  if (typeof sig !== 'object')
    sig = parseBytes$1(sig);

  if (Array.isArray(sig)) {
    sig = {
      R: sig.slice(0, eddsa.encodingLength),
      S: sig.slice(eddsa.encodingLength)
    };
  }

  assert$9(sig.R && sig.S, 'Signature without R or S');

  if (eddsa.isPoint(sig.R))
    this._R = sig.R;
  if (sig.S instanceof bn)
    this._S = sig.S;

  this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
  this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
}

cachedProperty$1(Signature$2, 'S', function S() {
  return this.eddsa.decodeInt(this.Sencoded());
});

cachedProperty$1(Signature$2, 'R', function R() {
  return this.eddsa.decodePoint(this.Rencoded());
});

cachedProperty$1(Signature$2, 'Rencoded', function Rencoded() {
  return this.eddsa.encodePoint(this.R());
});

cachedProperty$1(Signature$2, 'Sencoded', function Sencoded() {
  return this.eddsa.encodeInt(this.S());
});

Signature$2.prototype.toBytes = function toBytes() {
  return this.Rencoded().concat(this.Sencoded());
};

Signature$2.prototype.toHex = function toHex() {
  return utils_1$1.encode(this.toBytes(), 'hex').toUpperCase();
};

var signature$2 = Signature$2;

var assert$a = utils_1$1.assert;
var parseBytes$2 = utils_1$1.parseBytes;



function EDDSA(curve) {
  assert$a(curve === 'ed25519', 'only tested with ed25519 so far');

  if (!(this instanceof EDDSA))
    return new EDDSA(curve);

  var curve = curves_1[curve].curve;
  this.curve = curve;
  this.g = curve.g;
  this.g.precompute(curve.n.bitLength() + 1);

  this.pointClass = curve.point().constructor;
  this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
  this.hash = hash_1.sha512;
}

var eddsa$1 = EDDSA;

/**
* @param {Array|String} message - message bytes
* @param {Array|String|KeyPair} secret - secret bytes or a keypair
* @returns {Signature} - signature
*/
EDDSA.prototype.sign = function sign(message, secret) {
  message = parseBytes$2(message);
  var key = this.keyFromSecret(secret);
  var r = this.hashInt(key.messagePrefix(), message);
  var R = this.g.mul(r);
  var Rencoded = this.encodePoint(R);
  var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
               .mul(key.priv());
  var S = r.add(s_).umod(this.curve.n);
  return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
};

/**
* @param {Array} message - message bytes
* @param {Array|String|Signature} sig - sig bytes
* @param {Array|String|Point|KeyPair} pub - public key
* @returns {Boolean} - true if public key matches sig of message
*/
EDDSA.prototype.verify = function verify(message, sig, pub) {
  message = parseBytes$2(message);
  sig = this.makeSignature(sig);
  var key = this.keyFromPublic(pub);
  var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
  var SG = this.g.mul(sig.S());
  var RplusAh = sig.R().add(key.pub().mul(h));
  return RplusAh.eq(SG);
};

EDDSA.prototype.hashInt = function hashInt() {
  var hash = this.hash();
  for (var i = 0; i < arguments.length; i++)
    hash.update(arguments[i]);
  return utils_1$1.intFromLE(hash.digest()).umod(this.curve.n);
};

EDDSA.prototype.keyPair = function keyPair(options) {
  return new key$1(this, options);
};

EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
  return key$1.fromPublic(this, pub);
};

EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
  return key$1.fromSecret(this, secret);
};

EDDSA.prototype.genKeyPair = function genKeyPair(options) {
  if (!options)
    options = {};

  // Instantiate Hmac_DRBG
  var drbg = new hmacDrbg({
    hash: this.hash,
    pers: options.pers,
    persEnc: options.persEnc || 'utf8',
    entropy: options.entropy || brorand(this.hash.hmacStrength),
    entropyEnc: options.entropy && options.entropyEnc || 'utf8',
    nonce: this.curve.n.toArray()
  });

  return this.keyFromSecret(drbg.generate(32));
};

EDDSA.prototype.makeSignature = function makeSignature(sig) {
  if (sig instanceof signature$2)
    return sig;
  return new signature$2(this, sig);
};

/**
* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
*
* EDDSA defines methods for encoding and decoding points and integers. These are
* helper convenience methods, that pass along to utility functions implied
* parameters.
*
*/
EDDSA.prototype.encodePoint = function encodePoint(point) {
  var enc = point.getY().toArray('le', this.encodingLength);
  enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
  return enc;
};

EDDSA.prototype.decodePoint = function decodePoint(bytes) {
  bytes = utils_1$1.parseBytes(bytes);

  var lastIx = bytes.length - 1;
  var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
  var xIsOdd = (bytes[lastIx] & 0x80) !== 0;

  var y = utils_1$1.intFromLE(normed);
  return this.curve.pointFromY(y, xIsOdd);
};

EDDSA.prototype.encodeInt = function encodeInt(num) {
  return num.toArray('le', this.encodingLength);
};

EDDSA.prototype.decodeInt = function decodeInt(bytes) {
  return utils_1$1.intFromLE(bytes);
};

EDDSA.prototype.isPoint = function isPoint(val) {
  return val instanceof this.pointClass;
};

var elliptic_1 = createCommonjsModule(function (module, exports) {

var elliptic = exports;

elliptic.utils = utils_1$1;
elliptic.rand = brorand;
elliptic.curve = curve_1;
elliptic.curves = curves_1;

// Protocols
elliptic.ec = ec;
elliptic.eddsa = eddsa$1;
});

var elliptic$1 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  'default': elliptic_1,
  __moduleExports: elliptic_1
});

exports.AEADEncryptedDataPacket = AEADEncryptedDataPacket;
exports.CleartextMessage = CleartextMessage;
exports.CompressedDataPacket = CompressedDataPacket;
exports.LiteralDataPacket = LiteralDataPacket;
exports.MarkerPacket = MarkerPacket;
exports.Message = Message;
exports.OnePassSignaturePacket = OnePassSignaturePacket;
exports.PacketList = PacketList;
exports.PrivateKey = PrivateKey;
exports.PublicKey = PublicKey;
exports.PublicKeyEncryptedSessionKeyPacket = PublicKeyEncryptedSessionKeyPacket;
exports.PublicKeyPacket = PublicKeyPacket;
exports.PublicSubkeyPacket = PublicSubkeyPacket;
exports.SecretKeyPacket = SecretKeyPacket;
exports.SecretSubkeyPacket = SecretSubkeyPacket;
exports.Signature = Signature;
exports.SignaturePacket = SignaturePacket;
exports.Subkey = Subkey;
exports.SymEncryptedIntegrityProtectedDataPacket = SymEncryptedIntegrityProtectedDataPacket;
exports.SymEncryptedSessionKeyPacket = SymEncryptedSessionKeyPacket;
exports.SymmetricallyEncryptedDataPacket = SymmetricallyEncryptedDataPacket;
exports.TrustPacket = TrustPacket;
exports.UnparseablePacket = UnparseablePacket;
exports.UserAttributePacket = UserAttributePacket;
exports.UserIDPacket = UserIDPacket;
exports.armor = armor;
exports.config = config;
exports.createCleartextMessage = createCleartextMessage;
exports.createMessage = createMessage;
exports.decrypt = decrypt$5;
exports.decryptKey = decryptKey;
exports.decryptSessionKeys = decryptSessionKeys;
exports.encrypt = encrypt$5;
exports.encryptKey = encryptKey;
exports.encryptSessionKey = encryptSessionKey;
exports.enums = enums;
exports.generateKey = generateKey;
exports.generateSessionKey = generateSessionKey$1;
exports.readCleartextMessage = readCleartextMessage;
exports.readKey = readKey;
exports.readKeys = readKeys;
exports.readMessage = readMessage;
exports.readPrivateKey = readPrivateKey;
exports.readPrivateKeys = readPrivateKeys;
exports.readSignature = readSignature;
exports.reformatKey = reformatKey;
exports.revokeKey = revokeKey;
exports.sign = sign$6;
exports.unarmor = unarmor;
exports.verify = verify$6;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ELF          (    R  4      4    (     p                                         ! ! ! |             ܪ ܪ ܪ                      $   $         Qtd                          Rtd! ! ! 4  4                 GNU nԤ!i2+s+      @      @          B@ Q
       0$   (   D  A     $  @  Jj	 A  d          <   0    R`  " @@R  $   D @!  `   VD  %"  ! 
p  $         l  A  #FPP`@                                                                                                                                                                                                                                                                                                                                                                                                                                                                           	  
                                                        !  %      )          ,  -                  .  /          0  1  3  7  =  ?  @          C  D  E  F  G          I      K  L  O      P      3mW#.p!9­ʸN'-ʍE{)p6@_7@_+~:+~N؍WQFB&L'v9M'vt*l2gJ:POo=>}M6ҵ^^^2~#\%}Batlc&}i%E{!dNP@k"3uu>dMNhthe{kt97HĔ48ke{kB{!le{kle{k,oe{koe{k7qe{kr3r3xm`Ħ΋M-߀߀߁vȂo"a:[󐯡Pі3WSyެ>!sV3W'JRV3QzӥR93E
lcyy)A*:)A˷)wd(eִ='?{:ݬ|8jI}jIt)(Ǌ6{9OFfufu	fu Dl?Iyzfl@ÌIyzz6 2 *p+tB5[}e KaR}jrZ:Ø9Ø99/1>!N!Eo$jmja+	ڌ
*Rt*Rt+Rtn1; DQ_Ey%ks`eF;ZPpsPpsܵTnTʨ@ݵ/g5?ecru%A(/҈Q%mW":tU%6-7ɥ
rM`|BrM
'т$UN                    DG       
                                        "
             <                          :             A             ;                           F           "   
             
                                         
             1                                                                                $                                                     8                          $                                                                 
                                       d             
                                        )	             "                                                     	                                                    W                          
	                                                    y                          
             h             	             
             W             
                                                    {
                           M             
             	                            
             )
                                        u
                                                     <	                                       i
             F             y	             
                          %                                                      N             n             
                          [             T
             *                                                    u                                       X             m	                                                                 b                          	                                                     ,               .                          |
             k             ^             G                          	                                       *                                       )
  (       6          h         i l       t         |       4  8I      n        	  0]               k ,       $D         V      -  ,          @     -        f  |         <  L       m        g |       (          H              t      I  P      =  >               
  tJ        x        j        `         < $       Ȉ               >           xk      
  h \     
  j      ]  F T         p     W	  <h      
  d      B  ,  <       x p     
    L    I  pJ               $O              }           -  pE X                \  xU        =                   L                   H  @                  X @                                                    <     	    H     "  ` <     	  ؁         k 8     D  l       s  V      	  X  H     	          	    $     	         1  P d              P  @               P         f
  TY 8    q  $d T                Я       
  @k 8     +  ,        ; ,     	  (  0             U             P t                h      q  |     
    ,       DA (                j      .         f             M     x   X  H       $ <     U  Q      	  \ h     z  T       
    L        $     _  `w     l     $    T           k 8       H      3  `         8       3         B
  j        Ę       u  ȏ       t   C X     
    ,         <        ` <        P 8         d    e  ?       xC      2  m        P                 P        F     H	  xd       ~                 ~          ,     W
  j        i ,       p      <  Dj      T                         \  E      	  ؁       1
  d      1
  d        h                a  (K      '  hi      6  r     D  |C      )           h     C   V                $ x             
  V               
  $T      
  X @     	  (T P    '
  (         N     m         
  d         t    }  i P     a        
    4             [
  j        lA      [
  hj        xU        0 @       `j      k  (         H       
  `          $                $ <     E
  TY 8      x       M  Ȉ       O          q D       $ x       j ,              J X     e                  	            $     $  j 4        $             h
  Z @       p  H    -  \Q ,      __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize fuse_new_compat2 fuse_new_compat22 fuse_new_compat25 malloc free memset realloc strcmp pthread_mutex_lock pthread_mutex_unlock strlen memmove strncpy pthread_cond_init pthread_cond_wait pthread_cond_destroy pthread_self fuse_req_interrupt_func fuse_req_userdata pthread_kill gettimeofday pthread_cond_timedwait __stack_chk_fail __stack_chk_guard pthread_cond_broadcast mmap64 pthread_getspecific pthread_key_delete memcpy fuse_add_direntry __fprintf_chk stderr dlclose __assert_fail clock_gettime __errno_location perror abort strdup pthread_cond_signal munmap fwrite calloc pthread_setspecific fuse_req_ctx fuse_reply_none fuse_reply_entry fuse_reply_err fuse_clean_cache sleep fuse_notify_poll fuse_lowlevel_notify_poll fuse_session_process fuse_session_exited fuse_get_session fuse_loop fuse_session_loop fuse_session_next_chan fuse_chan_bufsize fuse_chan_fd fuse_session_receive_buf fuse_session_process_buf fuse_session_reset fuse_invalidate fuse_exit fuse_session_exit fuse_chan_recv fuse_get_context fuse_fs_getattr fuse_fs_fgetattr fuse_reply_attr fuse_fs_rename __snprintf_chk fuse_fs_unlink fuse_fs_rmdir fuse_fs_symlink fuse_fs_link fuse_fs_release fuse_fs_opendir fuse_fs_open fuse_reply_open fuse_fs_read_buf fuse_buf_size fuse_fs_read fuse_buf_copy fuse_reply_data fuse_fs_write_buf fuse_fs_write fuse_reply_write fuse_fs_fsync fuse_fs_fsyncdir fuse_fs_flush fuse_fs_statfs fuse_reply_statfs fuse_fs_releasedir pthread_mutex_destroy pthread_mutex_init fuse_fs_readdir fuse_reply_buf fuse_fs_create fuse_reply_create fuse_fs_lock fuse_reply_lock fuse_fs_flock fuse_fs_chown fuse_fs_truncate fuse_fs_ftruncate fuse_fs_utimens fuse_fs_access fuse_fs_readlink fuse_reply_readlink fuse_fs_mknod fuse_fs_mkdir fuse_fs_setxattr fuse_fs_getxattr fuse_reply_xattr fuse_fs_listxattr fuse_fs_bmap fuse_reply_bmap fuse_fs_removexattr fuse_fs_ioctl fuse_reply_ioctl fuse_fs_poll fuse_reply_poll fuse_fs_fallocate fuse_fs_init fuse_fs_destroy fuse_fs_chmod fuse_getgroups fuse_req_getgroups fuse_interrupted fuse_req_interrupted fuse_is_lib_option fuse_lowlevel_is_lib_option fuse_opt_match fuse_fs_new __memcpy_chk fuse_start_cleanup_thread fuse_stop_cleanup_thread pthread_cancel pthread_join fuse_destroy fuse_session_destroy sigaction fuse_register_module pthread_key_create getpagesize fuse_opt_parse fuse_session_add_chan sigemptyset __sprintf_chk dlopen dlsym fuse_opt_add_arg fuse_opt_free_args dlerror strerror fuse_new fuse_kern_chan_new fuse_new_compat1 __fuse_exited __fuse_process_cmd __fuse_read_cmd __fuse_set_getcontext_func fuse_chan_session writev fuse_chan_new pthread_attr_init getenv strtol pthread_attr_setstacksize sigaddset pthread_sigmask pthread_create pthread_attr_destroy pthread_setcancelstate sem_post pthread_detach fuse_session_loop_mt sem_init sem_destroy sem_wait fuse_reply_statfs_compat fuse_reply_open_compat fuse_lowlevel_new_compat fuse_lowlevel_new_compat25 fuse_chan_send pipe fcntl64 posix_memalign vmsplice fuse_session_data fuse_dirent_size fuse_add_dirent fuse_reply_iov fuse_reply_ioctl_retry fuse_reply_ioctl_iov fuse_pollhandle_destroy fuse_lowlevel_notify_inval_inode fuse_lowlevel_notify_inval_entry fuse_lowlevel_notify_delete fuse_lowlevel_notify_store fuse_lowlevel_notify_retrieve getuid fuse_session_new fuse_lowlevel_new strstr strtoul fuse_opt_insert_arg fuse_loop_mt_proc fuse_chan_data __fuse_loop_mt strchr strncmp __isoc99_sscanf strcpy fuse_opt_add_opt fuse_opt_add_opt_escaped fuse_chan_new_compat24 fuse_session_remove_chan fuse_chan_receive fuse_chan_destroy fuse_set_signal_handlers fuse_remove_signal_handlers pwrite64 pread64 cuse_lowlevel_new cuse_lowlevel_setup fuse_parse_cmdline fuse_daemonize cuse_lowlevel_teardown cuse_lowlevel_main fuse_setup_compat2 fuse_setup_compat22 fuse_main_compat2 fuse_main_real_compat22 fuse_setup_compat25 fuse_teardown_compat22 fuse_main_real_compat25 fuse_mount_compat25 __realpath_chk strrchr fork setsid chdir dup2 fuse_unmount fuse_main fuse_version fuse_mount_compat1 fuse_mount_compat22 fuse_mount fuse_main_real fuse_main_compat1 __fuse_setup __fuse_teardown iconv iconv_close iconv_open setlocale nl_langinfo fuse_unmount_compat22 socketpair recvmsg waitpid setenv execv execvp geteuid umount2 __xstat64 getgid stpcpy sigprocmask setuid execle __lxstat64 setreuid readdir64 closedir fopen64 fgets fclose libdl.so.2 raise libpthread.so.0 libc.so.6 ld-linux-armhf.so.3 libfuse.so.2 FUSE_2.2 FUSE_2.4 FUSE_2.5 FUSE_2.6 FUSE_2.7 FUSE_2.7.5 FUSE_2.8 FUSE_2.9 FUSE_2.9.1 GLIBC_2.4 GLIBC_2.28 GLIBC_2.7 GLIBC_2.17 GLIBC_2.5                     
                                                                                       
                                   	                                       	          	     
 	                      
        	        	  	                     	     	          	 	        	      	              	           	          -j      p           !{
      }           !{
   $        }           !{
   $                   !{
   $                   !{
   $                   e!   $                   !{
   $                 	  !{
   $                 
  a!                    1         ii
           \         ii
           R     `           ii
                ii
  
      ii
           B         ii
         !    !    !    !    !    !    !    "    "     "    ,"    8"    D"    P"    \"    h"    t"    "    "    "    "    "    "    "    "    "    "    "    #    #    #    (#    4#    L#    P#    T#    X#    \#    `#    d#    h#    l#    p#    t#    x#    |#    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    #    $    $     $    ,$    8$    D$    P$    \$    h$    t$    $    $    $    $    $    $    $    $    $    $    $    %    %    %    4%    @%    L%    d%    |%    %    %    %    %    %    %    %    %    %    %     &    &    &    $&    <&    H&    T&    `&    l&    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &    &     '    '    '    '    '    '    '    ('    ,'    0'    8'    D'    P'    \'    t'    x'    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '    '     (    (    (    (    (     (    ((    4(    @(    L(    X(    d(    p(    |(    (    (    (    (    (    (    (    (    (     )    )    )    $)    0)    <)    H)    T)    `)    l)    x)    )    )    )    )    )    )    )    )    )    )    )    *    *     *    ,*    8*    D*    P*    \*    h*    t*    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *     +    +    +    +    +    +     +    $+    (+    ,+    0+    4+    8+    <+    @+    D+    H+    L+    P+    T+    X+    \+    `+    d+    h+    t+    x+    |+    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +    +     ,    ,    ,    ,    ,    ,    ,     ,    $,    (,    ,,    0,    Ԫ    ت                                     (    ,    <    @              6   I   w      G                 $   (   ,   0 	  4 
  8   <   @   D   H   L 
  P   T   X   \ 1 ` @ d   h   l   p   t  x   |          	                    8                    !  Ĭ "  Ȭ  ̬   Ь  Ԭ   ج  ܬ #      $   %         &   '   (    )   *   +   I        ,   -     $ .  ( /  ,   0 0  4 1  8   < D @ 2  D 3  H 4  L 5  P 7  T   X 8  \ 9  ` :  d ;  h <  l =  p >  t ?  x @  |            A   B   C   D   E   F   G   H      &  I   J        ĭ   ȭ   ̭   Э 9 ԭ K  ح L  ܭ '  M   N   O              P    Q   R            S      T      $   ( U  , L 0   4 V  8   < W  @ X  D   H  L Y  P : T Z  X 
 \ [  `   d \  h ]  l   p 4 t   x   | ^      _   /  )           `      a      b   c     d       Į   Ȯ 
 ̮ e  Ю f  Ԯ C خ   ܮ    g   h   i   0  j   k   l   m    n          o   .         $  ( p  , q  0  4 H 8 r  < s  @   D 2 H 5 L   P t  T u  X J \ N ` v  d  h E l   p F t P x   |       ,        x   y      Q     z   {   |   O  }   ~       į   ȯ   ̯ - Я   ԯ B د   ܯ   @- -d  Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ| Ə6ʌt Ə6ʌl Ə6ʌd Ə6ʌ\ Ə6ʌT Ə6ʌL Ə6ʌD Ə6ʌ< Ə6ʌ4 Ə6ʌ, Ə6ʌ$ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ| Ə6ʌt Ə6ʌl Ə6ʌd Ə6ʌ\ Ə6ʌT Ə6ʌL Ə6ʌD Ə6ʌ< Ə6ʌ4 Ə6ʌ, Ə6ʌ$ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ| Ə6ʌt Ə6ʌl Ə6ʌd Ə6ʌ\ Ə6ʌT Ə6ʌL Ə6ʌD Ə6ʌ< Ə6ʌ4 Ə6ʌ, Ə6ʌ$ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ| Ə6ʌt Ə6ʌl Ə6ʌd Ə6ʌ\ Ə6ʌT Ə6ʌL Ə6ʌD Ə6ʌ< Ə6ʌ4 Ə6ʌ, Ə6ʌ$ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ| Ə6ʌt Ə6ʌl Ə6ʌd Ə6ʌ\ Ə6ʌT Ə6ʌL Ə6ʌD Ə6ʌ< Ə6ʌ4 Ə6ʌ, Ə6ʌ$ Ə6ʌ Ə6ʌ Ə6ʌ Ə6ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ| Ə5ʌt Ə5ʌl Ə5ʌd Ə5ʌ\ Ə5ʌT Ə5ʌL Ə5ʌD Ə5ʌ< Ə5ʌ4 Ə5ʌ, Ə5ʌ$ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ| Ə5ʌt Ə5ʌl Ə5ʌd Ə5ʌ\ Ə5ʌT Ə5ʌL Ə5ʌD Ə5ʌ< Ə5ʌ4 Ə5ʌ, Ə5ʌ$ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ| Ə5ʌt Ə5ʌl Ə5ʌd Ə5ʌ\ Ə5ʌT Ə5ʌL Ə5ʌD Ə5ʌ< Ə5ʌ4 Ə5ʌ, Ə5ʌ$ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ Ə5ʌ    @-00  t] 0 0   R/OX   , ,0  0  S 00/ 0  S//] ] X   8 80  0 C,0A0/ 0  S//\ \ dX    L0L 0  0  S/80@-0  S  
(0 0 0  t\ $X    \ 4\ 0  Sd00`  S  
X000000  SP000  ST00/  /O- $M Z @   0  
0  `0   P  V P   
HH  \E  
" Q P;   0
 S`=  
 P03  !@ R3    Rࠣ ࠳ T ࠳  ^L    R   0 T 0S  0 Z
  
       0(0      $Ѝ0V   0(`(  \0V 0 00  P0 A!0R00 00  T0С
 V0   P0,   Z0ȱ  T0ȱ(0  0  !   S  Ry 00P@ V` p      (0p(0(` h f$ c@-0  @  a  0        
  R    Ѐp@-P	Up8` @  %QP`  P  p0p@- @  P  P	  
    !   P p  pO- `(Q M  
a 몀 0  @ #b  p S	 R0@!0! S 0  *Ѝ Y
  0P  		A   0  a  0 P a   S  RP! Y0 01@0A @  T
0 X ЍOy7p@-,@ T  *  TK Q    T   @ P  2  P0    @0,@  p  p@A-p  `   R  
  
2 = @\P     RP 0 a @   0a    S  R@!A  T     @  T  
00 S I  P A-8P @`p    @P  
(@  T @@  H0p@-@  T  
 P  @  T  
  #  P000 pU O- M PpK ` `    Y    PE I00	@ T  *  T   @  P  
 0	PE P    ) @ 	 I/00I Ѝ@\0A-@0P p\0  r 0 0 ` R      0  S8 @ *\0 
   T      0 T` 0X  0 p@-@ P0   E 0 80 p@   0 0G-M 00 P 0  S  
8@ 80  Sp`    b  l0 c1 10}80  S
 S  0 R  ЍN   A-8P` @p080 Q =    A 0O- `@M T  
 0    Q  
 x   0 Ѝ    @   @     0  R 0 "0 刀xӏ p p!  
PE  _  [0E  :0	 
     P0  000p @0 p@ 0@-H@@ H00C  S0  
( @     /  DTP ,P 0O-|Mp0  ` `  Jtu  f 0`F   3/t  0  P  R  |ЍYK   10O-M`  R 0 @p؊|0
 \  
h  P  U
  
	0   
40  S<  
 0@0|  0 RP  Ѝ   0  Q'
8  D   P08 tPp0i	0 0 40 0 (Py P  p   
(, P   B 0 h  (P0  p
  
(P0  0  B V00 P S* `    0'K   H  R  
 /@- @, , 
0     	0l0 4I    p@-@P `P { 0  S   0C  S 0   @  T  
0  S  0C  S0
   0    TP0    S   PP p@   @0@@ 0<   0000 0,    M L ~   R  ~    V  p@- T@ P@  ? ppe 0 S  
,   x 0  00 ppK  L - P0T c  
4 Q  
LLd408  , 8 QD U T@- ` pM @^  0 P ^     S  RP!`  P       P  
0 TЍ,0,  0  @  Z%y7F   |   R@-@  
P0 s 0P0:   P0 SP   R  
R&  
 r  
 0  R   
 r  
 BR P    T  RP   R0 0 0  
t0tt 0/0  \0\\ 0X 0  H0HH 0/0  0| `    | <  {     {  P O-|$M@00 P ̠ P  @HL`" P {  
 TPP  
 0  PPR  
  [e  
  Vo  
 
	  0P0  
P0  S?    0P0
	 80 @ S=  
0  S%  
   R"  
p     V  
P0  SG  0P0@0 S'  
0  S  
  Q
  
   P  VP  
0 
	 >    VP 0   0 R&  $Ѝ
P1P0
PPP 0   S  
  0E B 0  [ 0P0 P 0L0000
PP((0(( 0$ 0  >D   \  y 0~    O-  M`  R p	  
  
2 = @\P     R0P0  0] P@   0]  	 	 S R@!    P  T0    P 0p0000! S  a0	  *  Ѝ   P   0 Y
	A  0  T 	(  
0      R	  
2 = \     R  0`] `   0Z]   S  R 1 Y 0 01@ 0A @  T0 S0  \0p@-@  P	  
D  0  R8  \\  0\  pT  0  R   HO\00\0p@0@-  SM@`"  
\  P 1  
   P0  S  
T   L H pP3  
 w  \    
 2  Pp  W  
 V
  
 Ѝ@8P0  S 	  
Ѝ \0 Xp0\0Ѝ@-D  < 8c pP  
 w\ \  \ \   \ 
 pA-8` P@ p   0@  T  
  @  T E AO-8` P( @,0p 
  0	   0@  T  
 t @  T "  O0A-T p SP `p  
 u@ @d@00C  S0  
0  R  
P 0 P 0  @0  @0  0   p   0    A<    y 0h"  SA- M  0C  S@0  
Ѝ P  QZ  P0  S~     0  S  x| x0  x0|00 p [  0 ` '\   S R`!!a  R  
 R     T  
 0  S ЍA~`0 0C(S  0*  W&  
 0G   0  Q!B  pg!   
  0C  Q 0   w   S   Q  	     [  p  W!1  R     0  S0     P0PP 0/,0  $8088 04 80  < y7  hw p u v tp u v >  C-M0R  YPF  
 0  ^  0	  
 ႂ͌`Xp  0  ^ `@   0[ p   0[    S  Rp!q  \U  
 T     0  SN  
 Sp   0    0 T0 P   
X0 0C "S0  :Ѝ  P  
0@@0!  R@  `   
   0C  R0   p     S    RЍ    P
 1  Q     0  S0    ,0 ( 0      dh9   t 0  S	  
p@-B  U T   T 0p@"^]0 0 D0  em r Lt   A-8P @`p   ( P  
  AyG-8p @`P $     ` 0  V0  
  P P  
  Y#      0   p  
 P N P  0   p
  Y
L00L0$ ,  0 P 0  -(6   r p@-lPl`P`   @P  
 p % @P  
  H p$0$ . 0   09 85   r p@- ` @ ` P    0  p4-, 0M       Ѝp4   <r p@-  \h``p  \@P  
   P
  
8  0,     p@ p@4   q O-|M8p` @ᠠ  t$ 0	   p P  
 t  0  R"  |Ѝ 0ZP0 ` 0X 0d0  0 	0PT 0, 0 	0 P 63   p p O-M @8` 00 00崠开00 p 0 
0	  O PP  
 u  
 U0   0 RO  Ѝ0 0! : PP
  X    0    u 0X P0 ` 0  00`d 0 	0 ptXp\hl2t
0   + M0L 0 	0 P 0 
0  x2   4o o n n @-M 0   @* p  0  S  ЍO- 8 M @P   AF
	 ;b  U T  P   RI  
X2 P0 0L2(@0000`   } X  R  

  |    | k 0 Q 0  9   0  S P  P0  S  
 !" S R
 w Q  !   0 S     P    

  Q P  P   R   	  z0  0 R=  Ѝ! S  R*  !P00 "   S R     Q     R
x| x (  $ (x |   }	  !V00 "0000 0, P0  
00   n n <d li k   @-@pp0  QM P`0
   T  
 0 Ѝ@0Ѝ,,  0 ` @  (-   |k A-P@ p  U  
 `R   T Ap@-P` @  0 p@  R  p@- P@ `  pp  Qp   0p@ bIO--T1T!0M` 8p    6 E @ P$0!  z !Jkz BK [*{Ek6[{5K  C  Q P!  h  R  xC ECg 
0	 S 0t  S  ʖS` < #àC`  0 R  Ѝ8088 04 \0  U5    eA+     gfff\a f Di   @- @ @-@       @    /O-TMq1p `P00 0L0k  
0 P  S
    @0L   0 Ri  TЍ  !( @  j@(@ 
  X( K  
 	 _ p00000`  `P)  0	 4`<`@`D`008K   R G bb!a   p @  
  P     p @
  P    K  `P
O     r
 U x l p	   p @(0( % 0   @ 0)     f  /  C-M(a(1` p    00  w   @P  
   P P    
  
 Q PP   0P0  0  R%  Ѝ0  0   0p0t % 0   0 @   @@OPP@
	  @<'     f e @-Pp@- @P`# 0 d  S   
   R   p@/8 8 0     Q 0 p@/% pd&   4e @-M @P`p0   S   
   R    Ѝ@/  U   
 0  S  
   R   Ѝ@/` !  T P   00 4 0      0% Ѝ%   `d ,d O-$M @H`    LPp3  U00  
0	     X  
 $Ѝ80 0e  [  
    p  W  
Т  Qc    [ Z`  x| x  x|\    pP  
!,P0 0 H`P` p  U0  
 u  
2 U  0	 p .V   S  Rp!1  S	  
  U  j    Rg  
0  S0p  S,PH`P	  
" 0   0"0   . p B  
0Т  Sx0x0|00  0 "|Ц'   P '  	  0  Sl
   0    P $Ѝ	   XP 	  P    pY* FFPw$ y7  Pa O-M883	P00 0 0% 0. S @    P `\  
0. S P5  
 0 0 0 W `PC  p0  S~  0  Sw     
0  p `  {@{${`0  S^  0  S  
     W   
8P c    8P Z0  Sq   L0     0  `PpP
 	
 0  0 R_  Ѝ8P 70  S5  dp T  0 ` .U     S  R`!q  W	  
0 S  &  0 X#  
p  W 
 t 
 R
  0    w0 0    00 00    0  `PP[,04  0   0j#|!   y7  8^ ] ] 10G-Mp 0 0MPh   @   Y?  
 0  S;  
0  SW  
 0 Q0N  	0 0  S `B  0  S  
     V  8`  L0   
$0  S0C$00  S8   #  R
 m  0 R-  Ѝ f
     0 E `  V0  S    Y  <0  S `
x 
 x
 ^   `6    p@-M @P` 0 d  S   
   R   Ѝp@/4 4 0    `   0% Ѝp   ([ O- @ఱM 0P8
p` 0	 
  O PP  
4 @0   4   i  =  P   $0   	   X  (0 h A$    p 	  
$ 0$  S  pW
  $p  W
   P	  
 0   0 R  Ѝ00 `
  0 	 R   Z |O-ttMp`P 0l0 1$  `0	  @ P  0  S$  0  S      P    p P&  
0  S  00$0   0 k
 l  0 R  tЍ(
 m0  ; P
( 
 @	 0 t    p@- @P0 \  S   
   R   p@/4 4 0     0 p@/% p   lW (1(0C-\MpP` 0 T00 0 0 @ P  0  S  0  S      P   * P  
0  S    < h	 T  0 R  \Ѝ	 0    	 7  2   p@- @P 0 \  S   
   R   p@/4 4 0     O0 p@/% pX   U 00C-\MpP` 0 T0?0 0 0 @~ P  0  S   0  S     X  
   h	 T  0 R  \Ѝ	    	    p@-M @P`0 d  S   
   R   Ѝp@/4 4 0    `  0% Ѝp   0T G-MPp` 0 0  0 0
 0 @ Pp  0  S    p P  
0  S  0  S  
   h 	   0 R  Ѝ	 $ 	 i
  p0  `T   p@-M @P`L$0 d  S   
   R   Ѝp@/4 4 0    `  x$0% Ѝp   |R 8O-0MpP@ 0 0 g   0   ` P   0  S    w  P  
0  S  00 0  
 	 ^  0 R  Ѝ	  	   0     pC-M @`PL 0  R0!  
   R  
 0     |00  Ё l   L R 00  R0  S  0ЍpC/ Ѝp00(   xk P @P lA-dM PR` @p    %  
  8- P E(0  S8  L 0C(0   
  S	   L    U  
 R     0 R*  Ѝ   R   R0  S
 P 0   P  
0  S
   I *,0,, 0( p0  oO`   dO E J N t  O-,M`q`1p @` 0$00dP0  U0  
0  S  0dP S   S  Z  
 5/ P ?o  R2 0  S%  $  0  R-  ,Ѝ  0     H   0  5/ P    080  !   $  &     N M O-,Mxax1` @p 0$08P0  U0  
0  S!  08P S   S  Z   S-  
  5/ P ?o  R2 0  S  $  0  R1  ,Ѝ	 5/ P  0   p  0  !p   t     0  5/ P    0D
     L L 20O-M`Pp 0 0    0 @ P=  0  S>    p P-  08  S0000  S0000  S.  0  Sp  	    	 (00(0 [ p+  
0  S  
   &  0 RT  Ѝ0  S  
  , i  	  L0    L0	 0L0`0  d z0;0, kz0C[K:{Dk6K{4{  L0 000 0	 0< 0  	   [L00L0
 x        eA   O-,M @`Xp< 0  R04  
0  S8  P  UI  
%p
  	 5/0  S    P  ,Ѝ  P1  A0 p%@!d!      P  81< 0   0  ,ЍP  U% 
0  S
0  0` 0     P  U(  P  
  P  
   0" 00% PP`P <
  p </  P0   S      H H (H A-HM`pF h@   D@ PP  
@  T  
 0  S  
 `  0` V: D  0  R  HЍ     0 P P,P(@0`40 P   \1\0O-dM`Pp 0 \0吠9 00  @ R01  
0  S7   ب0 r0  S /  0  S  
     Y    q@  T  
 0  S  
p P { 0P U: u\  0 R  dЍ  P
 i x k     O-\Mb2`  @P 0pT0 0  R0Q  
 0  S   0  S  0  S    [,  
 p  (;/ P 0  R? 0  S_   X8  T  0  Ry  \Ѝ1 0  R b  10  С !  뤰  [ 0    S  0,08<@( D0    $0   @0  S%P1$ 0   0  0P$0P
$0  ( @0 PP
  80 8PШ  p@03/ P$ 0 0  R    00Сx PШ GX00P00H0HH 0D 0  `     ] XD D \ <C B B 8 = B   p@-x@M`EX( @   @ P 0 0<   00$0C,^<  0 R  @Ѝpp   10O-dMp` 0 \0吠0 @  S%  
 000  S(   ب 80  S P!  0  S  
     U  	 |\  0 R  dЍ e	 S  PP0  S
	 > 	     @-M @pP`nP0l   S   
  Q    Ѝ@/8000  P   P0% Ѝ   @  G-PMPp` 0 L0 0 @  S  
 000  S   
0  0  S   0  S  
    i L  0 R  PЍ u P0  S
      @-M @pP`p0l   S   
  Q    Ѝ@/8000  P   +p0% Ѝ   (? 0G-(pMP` 0l0 p    @ 80<   Q00   
 000  S!  0	  z0  S   0  S  
    h
 sl  0 R  pЍ   P0  S
(
 X( 
 \   p@-M @`PH0d   S   
  Q   Ѝp@/400,     H0% Ѝp   p= C-|M⤁1 `P@p 0t0]D0   S 7  
0  S+   D` R 00  R0  S  
 R<qp  6/t  0 RD  |Ѝ R#    6/  P"b #ac!$b "P0D0 0    e  <D  0
  0000006/  P ?`!!? ȟ "0b D0|   7 7   @< H1H!0C-Mp  0 P03P`` P @  X%  0  S  
	    Q1  
 0  S P!  0  S  
     U  	 2  0 R  Ѝt  P 0 D PP  
 e	 y 	 0  S
   5 X5 p@-M @`Pl0l   S   
  Q   Ѝp@/<0  0   ( 0 l0 Ѝp8   9 `1`0G-pM@p 0 l0@    P	 w80<   Q00 %  
 ``0  S/  	  <0  S,  0  S  
   ? 
     
  l  0 R  pЍ  `  V0  S0  S4`` (
 ( 
 ((   l6 10O-|Mp` 0 t0V PH  @PP  
 D 
 (4PDp  
  0@  $(,z P  
 j	   0  S  
   t  0 R,  |Ѝ0  S#    0  S   "  Z#	  p   Z p	 }0 	 0	 kD   G- Q P M` @ 0p0Hh0   S   
   R  	   3/  0 R)   Ѝ0  S"  
   R     3/p0$  X    h0<0< 0    0% gt     5 5 T2TO-0MP@ p 0 0@    ` U80<  00$04 +0 040=  0h   RY  
0  SK  
 00 00(0@0400p  S_  Ы1 0  0  S M   0  [00@  @  [=    S  
  4(   \     R  0 R9  Ѝ40  S
( 0  P  	    R0	 0 N  :   [
 k   0 a     S4 
 @  @ 0   LG-M @Pp0 `  S` /  
   R    3/   R?o2 0  S @   Ѝ|  0 l 
0 	 0@0  !p   ,   Ѝ%@   T2 82 lO-dMP`p 0 0   0 0 0 @  P  0  S    
0  PP  
0 Pe  S  
 	 W    P`	 0  S  
   8  0 Ra  Ѝ	   0 l PP=  (0:	S  

   Q  
  0 0  S:  P0  S000 0  R%    S(  8P     (00(0W
 	  p
0  V Q
  0 [
     S00
 	  	    M-0M @p`PP (1  ^0 C  
   R&  
! VС0  .  

 V/  
 V$  
0  S"  
 S)  
 S*  
000!" ?ؠ""!  0  0ЍM/`X00PH@00800% 0Ѝ   T/ 0/ / . . . . . . G-XMPp` 0 T0 0 @  S  
 000  S   x0  0  S   0  S  
   FT  0  R  XЍ  P0  S

 
  BB   O-DM P@h`  V
  < `P  
 f <  0 R  DЍ p  d!8
 "	 
 Y   O-dM@0p 0`\0 P(  B!8 $
 H  \'  
$(!#!#"	0@p`0"С S
 R  
С! Z0	    P    ^  
 V  
(  \`p	@ 0 0 0 :  P    \  0 R  dЍ [  	@`p  Z  `0  
 Z0  0  0 ` U   (O-  @ M    Pp P5    
 0	  0M	 
0  ` 0  S   & y  
(p !8P $
  & v `  0  R
  ЍX  LX H    ,1,0C-\Mp`P 0 T0w0 @  S   
 000 !  0   S)  0  {0  S%  0  S  
   		 T  0 R  \Ѝ b0 
 P0  t& p
0 `  S
      00A-Mp@P 0 0(0 `  S  
 00 P  K0  S P  
    e   0 R  Ѝ 0   @-M @`Pp 0  ^0 .  
   R  
  Q !    
 Q  
 Q  
    |    0Ѝ@/H@80% Ѝ   & > 0' & & & &  G-PMPp` 0 L0 0 @  S  
 000  S   
0  0  S   0  S  
   B i L  0 R  PЍ  P0  S
   <<   @-M @P`p',0 l  S   
   R    Ѝ@/8 8 0   p   `Q,0% Ѝt   <% @-M @Pp`00h  Q0  
0  S   0 Ѝ@/44 0  `  )0% Ѝ   $ A-M @Pp`(0  Q0	  
0  S  ( 0 ЍA/  U"  
0  Q  
0  S   0 ЍA/d! X `   48 0  `  0% Ѝ,   # # A- M$a$1` @pP 000   S   
   R   3/  0 R0   Ѝ40  S)  
    R     3/0   0   l  00 0@ 0   8    40  % W8     " " p@-M @P`@|0 d  S   
   R   Ѝp@/4 4 0    `  l|0% Ѝp   " 00C-\M@P` 0 T0]    0 p P  0  S    .0  S   0  S  
    h	 T  0 R
  \Ѝ	  	 `   @-M @Pp`0 h  S   
   R    Ѝ@/4 4 0    `  	0% ЍP     1!0O-AM@MA-  0` 0 p  0J   7 PP#  0  S$  XI0 L 30  S P  L0  S  
     U   _0A=0   0 R  AݍЍ e HJ ; J      C-M @Pcj 0  ^0   
   R   0 ЍC/H 0 T< 0 	 ` % Ѝ    O-AM`p 0 0 } 0 0	 0 @ PP8  0  S   :	S 8  
J?   ' PP2  
0  S*  0  S  
    
 u  0 R7  Aߍ  0 0 $(,04B8 PP  
& u   P 	 0  P0	 0 0   P p   @-M @P`0p   S   
  Q   Ѝ@/@00 p4 0  @0% Ѝ   t G-MP`p 0 0  0 0 0 @ P  0  S  
   P  
0  S  0  S  
   o 
	   0 R  Ѝ	 + 	 p  0  gp   C-M @P`0p4PT0x  ^0  
0  S  00	  ЍC/8 8 0     `wT% Ѝ    G-XM@P` 0 T0 f    0 p P  0  S  | x	0  0  S   0  S  
    h
 T  0 R
  XЍ
  
    A-M @P` pX0t  ^0  
0  S  0  ЍA/8 8 0   p   `	X% Ѝ\    G-XM`@     0T Px: pP  0  S  |0  0
0 0  S p  0  S  
   T  0  R
  XЍ	 J	     C-@M`p P  T  
   P   
 @ 0	   P   ( ЍC a ЍC%@ @0  P ЍCk b  ЍC@-M @Pp`B\0 h  S   
   R    Ѝ@/4 4 0    `  m\0% Ѝ    C-\M`@     0T P pP  0  S  x0  0  S p  0  S  
   T  0  R
  \Ѝ	 	  d   A-@M` P+  T  
  a pP   
  @ 0  P    ЍA a ЍA @0  P ЍA b  ЍAk@-M @P`p0p   S   
  Q    Ѝ@/< 0   `  $  0% Ѝ   X 00C-\M@P` 0 T0    0 p P  0  S  x0  e0  S   0  S  
   Y  X  	 'VT  0 R  \Ѝ h	 	  	 UU   p@-M @P`A`0 d  S   
   R   Ѝp@/4 4 0    `  m`0% Ѝp    00C-\M@P` 0 T0^    0 p P  0  S    0  S   0  S  
    h	 T  0 R
  \Ѝ	  	 d   G-M @Pc80  ^0  
0  S	  40p0	  ЍG/< ! pP   $  % ЍL   D  O-M P! 00@Ġp^    `1   (  W  @ 5  0  SA  
 0$00  SF    T !  $f0  S PC  $0  S  
   q0	  0  0 R9   ЍO$@(   {80<   W80,0< @
  @P"  
  Z  

 W!  
  )0  S$    P `  0  S
H	  @	 H 	 CA$0$$ 0  0  W   d      C-M @pP0`  U`0-  
0  S   00	 5/   R?o2 0  S @   Ѝp0l 0    ?P0 <0  0 0     1 Ѝ%@T    p G-XMP`p 0 T0  00  @ R0  
0  S*   	0  G0  S   0  S  
     Z
   
T  0 R  XЍ  P
 j p   ^p   O-M @Pd؄P0  ^0  
0  S	  H 0
 ЍO/< < 0     ` % Ѝ    10O-`PlMp   d 堠0 @  S!  
 000  S$   ة Щ0  S   0  S  
   7 i d  0 R  lЍ  P0  S
     11   p@-P @ 0  R00<00  S0000  S0;0t0  Sp 3/ pp@-@ P* 00000000 P0 0p@h@- @x0   S   
 3/   P  
 % @p@- P @@@@@@@ P w@pp@- @P`(0  S  
 p@/% pßO-MP     `h   @   Y0E?o2 0  S=  
0  S9  
0  S6  
0  S  
0   S m  
  
#   p  W@   00  R  
  S  
  1   00   H0    10    P0    px      0  p  W1  0  S2   5   =  
      00  pPx  
0  SD  0  S  
   8  W  0  S-    
 0  0 R_  Ѝ g
 
  
  ! pP  
  Y# I p8P   Y 
 	0 S  H0L  0PT0  0. p  W  Y  
	0   p  : pz  j p10 [   @-p@-P @ p@ @-   P@/@- @  P  
       6 A- Qp `pP
    @P  
  V㸀  
 0 H0H A 0   0P 0$ ( 0   0|   8 T 0  S    /    P0  S/p@- @8P -    p@424"0C-M`  P 0  R0  
0  Sa  0  S\  
u   P Rp3  
0A  T    @  T  
L0 
	0p p   x  P  @  T  R  R  
 p0A  T	  
 @M   T B  p R 0 R,   0 R    8     n  0 R   Ѝ 0@       .L0LL 0H 0  8088 04 0  d   $  T   -     0   ,  80  0 $0 S0   00     /P , O-M@PPɟI@  `]  p(t(0  S4 
l@ ZP  U  P    P <9P0 P  PP 

   pP	 
 ,0 #10   Q   08       
&'p2 $0  $0(0x(x80 P 	  p  
`  VH  
@8@(0 00,0(8( 0080$0 0@: S  S  
0  S: S  S   0    R*  
@  0 p!t1 k P  
 t0	 3/  P 
0崠   
    
    0   
0 00`0  T0  S'',2," S 00  R 0  S  
	 R  pw  
	 0    P    
30  S    @j0,@0@` 4 P ` 
@@` +  P ` 
@ @8   @P@ 
0T   Sx0x0|0 6 0050  S  b0     0" :0!  0 R* ߍ踀    p= 
`  V] 	 l5	 0p1   p00<   6 4 2   0 x0 * ( P 00 0  S`c
:4 4 0(0 @  0P0  
0   `M  P  
0 $  P    
 @  0P 0  
$0   `4   T  P   
  0 R( $0|  
  
   l , v  Z#0@   Z#0   T#0   N0$0  S
P3\C\ @ 0  L  @  T%  
,,,4`	 0 004080<0H p  
	 C p
  
 0   00 3/  Pq   @  T   !Rh2% 0   0QD20 @`"  0 
 n l<   6("0      ]    P  
 W U10 `%!  0  x10 @!  0  H1 0   0 1T 0   004 0   010!0    0  0   0p0  0   0 갼   t2   gd   ?1 qX T $ P   `H        P  L  <  4   4     t   ,          l          L  H      H  $  -M  VЍG-M`P  @ p @@@W p  
 Z
  
 O p  

 J p  
  @P  
80 0 	0 $ @   0  R  Ѝ  @   h ,  -M Ѝ-M0 0d0Ѝ-M0 0P0ЍD  p@-M@P`x P   
 0  PЍp@- p@O-M `  pP4  
    t   U   
 	 P @ k 0P
 @ Ѝ' T0  0   0@ U
  
 U U   @e ЍL    00@(0(( 0   x         (  8  p@- @Q  
P `B  p  
  p. @   P  
#0T0  P 0  S    dp,   i 0   0C 0  H  H  h  x  ll l00p@- `P M 0
@0  0*!
R!*3   0 R  Ѝp@   H O-,M Q 1P  @ 0$0#  n `P pP$  
  P     ` p 
  P    q  P
  $  0 R  ,Ѝ,0, % 0   0	  뼭       G-JM\a\1`
P p  0$14  ! @P  

  #    P(  @     $@   
0	     p    W  $! 0  R  Jߍ`` 0    <0  p0 @,   0 b뜬           p@- P `` @P  
$ L P  P    
   p `$  
 ( 0 ` 0  @(@ 0 pl0l * 0   0 `pD0H % 0   0g  `        8    2"0G-(M@ ` 0p$0   PP8  $0 0 PPPP      z
  ZC   P0  S8   0      * R R    S0  
 #   l 0
 S      PP
@ H$  0   R1  (Ѝ0C  S0,  
    N n00
 S0P   R  
  L
   0T0  0C B  !  R A ? 2    1!0C-dMPX   p  \  $p @X@@ @D,`( 9 0`,`4  m >   @   T  
  J *\  0  R+  dЍ  3  P
 0@ T  
 V@ T0 T00@ T  
     0  z  0@ TX@'   p@- @P  Pp  Up  0 @  R @0p@-   @  q  P ` 0     Q P   
   R   Ѐ  @- @   @0@-  S @  
02  S
  
4  P   
4g } @z40  S
 3/   -  RM  	  
 R  
l 0   Ѝ 0L L     Ѝ0 0 0 0  ЍФ   t    f    C- @ P`   1  R0MT  o EqZυ \  
  Q P       S  R  
Pp \ \  
$ Q P  -  $ S  R)  
P \2 PT0P@BЍC0 00P  0H@0 L  X  
	 8/  00C  S0  
   ЍC88 0    l        O- PSM@` p6  
0  0 S    0  S  
؀0	   
  [  
  k 0 0  
 8  ЍO H 
  +  , 0
  # D       p  p@-   `PP @P   ; P @   pX0  d0 PPH   0  p$0( ! 0   0 @0   `  P  @-M@F p  
 P    Ѝ` 0\    @   400 @  $   0  ꈠ   H    p@- P  @P  
  p  
+  p  
+  p  
L0 0   0 2 0 p u s  @ p p@- @   PPp    p@hp@-X P X00 @P	  
0 PP@T@0   p$ !  0  0   p     O- pttƟM @    ` 82    00 0@D0H0T0X0 P  PP \  @ ^  *< 1    
 ^  @   R0圥
 0 0 P(  : 
 R%    "  
4?(0 0P$0 0  
  0   P   $, 
  #     S  F     R7     0 Q( 0  xPhl0p0|00   0  S  0  S8  
4 0<   PP  < h  y PP6  1P 0 v P J0   0 R  Ѝ  4040 p  
  S$0    $ 0	   p   0  1!P 0 I P  Pe n   \  
XX#0     P( $0  0\ @ T0! 0P8      U     R@       R 0 0  0 @$0@P$D@00@   0      pw  
0   Q P
\`"0      PX 0P$0
 0. s s	   s0 824$  < Pc      h  8 xP40lp| PP840 h p0 0P405    0[0 @P5  
0$0     P   U0:  $ 
0  0 PP$  

 uh$  0 0 00   @@s P  Pe  P
 ,0Y,0`
 TPF0 ,0   r P
 F
 C6ꄞ   $          P (  0  {ok   0{C-  00\  {O  Jk0jFk^M  JF{7{I  JYk{Xkd1{'{:{Nk 0{F  {:  Jk 00jFk^7  JF{7{3  J>k{=k{'{&`P`XC$"$d l(h$t@pdȟ`Tx\dC#eX\`   0! 0   0!    0!   0!  Av?    eAɚ;O-Mb2`Pp@  0 |0  
 R    0
     PP    P|  0  R  Ѝ?40 P;  
 0 S
  *0  S
 4 P p 00
 P  :
   
0
 Q P 0	 0 P   u  
' Uc  10  0P0 U0P 0   :   
P  P
0 S1  
0 S S)  0 Pc804  `X  \,   T( (P PU 0P   U0 0!    0 P   	 Pxp   cP0 @d   0  i_00<  0   0P^     8   @  |    (  p@- @ `o PP0T  PEHL P0T P  Up  p@C-ρ``M\  @P  *`
    	0 <   `  0 R  Ѝ, , 0     B!t       h0h0p@-M@  R 0 0 00  P `   0  R  Ѝp뼑    0@- @4 0  R  
 2/   @  /O- @ rb 0І#60`0
  P`E   V       A- M`pO^ P @@  V @  T P   Ѝ"     ЍXX0p@-M@ 0  a `T P 8  0 R   Ѝp}   A-P pa  @P  
 F 80   5 P    A00O-DMP p @`    <V  Р"  Z  
Ё    :/<  0 R  DЍ &4(   0C-04M @  Pp    ,*  0 `0  V0   
00	    6/,  0 R  4Ѝ  0P	  
 <    & t   10O-@`p  VDM     P<    
0)  
0      (  , 0  P    Y  
 
`   9/<  0 R  DЍ D  D   Y &ur댍    00  S  
0@-M@ @3/Ѝ0&`00p@-0M `@P   U,  
0  S 0         $   800    5/,  0 R  0Ѝp&5v<    00  S  
  /&)G-ЀPM@ P`  (p 0  L0  
 0 S0      W0p  W  
  7/L  0 R  PЍ`  1( 
( 0尐  Y  
 p
0  9/ &'`     0 000G-HM`@a
`   p 0A  D0 0@  T
  
0 
	 4/D  0 R  HЍ	 &0   A-(M
0P@ `     $     0  p  W
  
   7/$  0 R  (Ѝ &x   000@-,M @P      U$00      

 5/$  0 R  ,Ѝ0bȈ   00C-<MP `p @    4  0 儀 0  X0$   
 	p   8/4  0 R  <Ѝ &5v4   G-(Mu5p @ `<  0P$0b 0  S              S 0     S   \3  0    R    Q5  R                    @  @  0;0    R
    00        000 0 
 R  0   P    Q  P R.=00  S0000  S  
0  S  
0  S0000  S  
0  S0;00  S0 00
YI"  :0 	 S00𐄅  S   
 3/, 0  R$ <0  R( 00  R< 0                      @  @   0 ;00 S0 0   1T! Sy   Ss  115  R0 #!!! 0  SC  0  S 3 #$  0 Rw  (Ѝ!!     0 SK
    S0            ^\!\!     G,4!	0    l!0@!    y 0   s 0   m  0   g 1   a   1 [ R   0 d 0   KP   0 Ex                         X  L  00A-(MP `
p @    $  0  0 R 0 !ā !́t0  S	  
  3/$  0 R  (Ѝ &렁    00  S   
/& 00  S  
  /&z 0-  ^  
0/&nA-@ `M PN 0p  W  0  
 P   P7/Ѝ &ЍASA-(M
0P@ `     $     0  |p  W
  
   7/$  0 R  (Ѝ &+l   0@-0 @,MP ` U P0  PP$`0P  0a10a !!x0  S  

 3/$  0 R  ,Ѝ5T   00O-<MP@    	  4+ 0  0 Q0$ā 0p   0 ( ́  [  
`
` 0;/4  0 R  <Ѝ &|~   00O-@ pP<Ml    Y4   
0 `      $ؠ    0  Pā  0́   9/4  0 R  <Ѝ&}    0-d  ^  
0 /&wA-@ PM pW 0``  V     
    0 6/Ѝ &ЍA\ 0X0  S   
/&U 0T0  S   
/&N 0-P \8  ^  
0/&> 00@-ML@ \8  T	  
P0  P  04/Ѝ0&Ѝ0@$p@- P @` 0\  ^    
0  p@/ &p@ 0H0  S   
/&10G-` pMD@    Q 3  
(h   P
 >! D%L P0@ D0  (0p x08 <0@ 8t |0  |0  0Dp
   07/  0 R  Ѝ0     @  &z     0A- ` 0 P @p(M   Q$          @0  S  
 3/$  0 R  (Ѝ
0     0 @0   S  &y    080  S   
/&O-@ `w M⌗ppPǟ 	hl  舐	  Pd   $܀`P   O  
  O P   PP  
`	 P  P5   0  S  
 &0 
S   & !   R  
   " &    P  
  !  P,#<   0  S:0 S  
 0 .  $0  0 Ro  ЍOP
R R
0  S   
R  &0  S  
0 S  Q  501  S
$ R&     
 P Z  (d501  0 S  Q
0B R S0 0 Q 00B Q 00) R 00  S

? (0͆Z? Z00	 
  S  R
   
4  ؤ [ Z  
P  P4( P0T P0T T10 PT0P P弁,
 0  P  
 P ZM   R*  
) R(*   ` (TR P(  
`  W V      S R  
P P `3  0   0St# +0  SO  
  PP  
   0*  0P `PJ	 ᘠ000  P a/  R(}  0  S+  20  "  D @ $8 
08  @<F(	 
 3/P0T @P0T 
10 T0P ( P弁w ` (``  @0    	 ᴐL( (<  \  0, H PT D0   @ B @ L  8 Q:  0#  (0
 03/0 
 0 R*(00  0 Z @	0
 @ 4/) R3
H  @ P   P B 1Z/T0P ( P弁;d0 * 0   0. P0PP 0L 80  x           | @     88  X  (        \@-T M@     
  0 R   Ѝp   @- @<   P  
   @UO-LM@app<`   P( P$P 0  ,0 (0  00(0D  P0C SP  @(0  :0(   S%  
    3/	 0   
 0 R  :0D  0 R  LЍH0H , 0   0 ? 9N,p     @   0O-@M  T  
  0ЍO/<  P  R  
    R  
,`p    p ؠ<  0<0   9/ 0 S    @ P, ЍO 0<0  S  
  /0 0 A-MP  ` 0 Rp0   0 R  Sx  

@    j    0 R  Ѝ耀m   0G- ` 0  PM @ 	 P   !xp3p#3
 > 0           0 R  Ѝ8m   O--1!0 p  P@tM 	 Q\   @`3h#lOF  >  J 00 
@^;  J@87  J@{ǋ?1 ({:H`X 0b0fP	 ȟLP0 0acЄT8XL\0T\0ʿ`
H0a@DUl  0 R  tЍ   0  0   0 H    Av?    eA\l   ɚ;p@- P @   p@00 0p@-M` A 0 0 00 0
00  0@00  0 R  Ѝpj   000@-,M @  P 0    U         $0
   
5/$  0 R  ,Ѝ0i   000@-,M @  hP 0    U         $0
   
5/$  0 R  ,Ѝ0\i   H0H0@- @M  0@0  0 R  Ѝh   00A-0M`   0,  < 0   @0   aa PP
   Q P,  0  R  0Ѝ =ph   0A-XM  aA  T` bAB ^ D00 3P #(
 ,0aB084<@DHL[T  0 R  XЍXg   |0| 0 0@-lM@0    Sd   
3/d  0 R  lЍ0 P\  F,0 
  D05g   H0H0@- @M  0@0"  0 R  Ѝ|f     @- M@
0   \          
a 
   `q`   0 R   ЍЀ  R  $f   D@-<M
@   00  0 R  Ѝde   C- @DM@`P  T< @$ ` P@(%   R!0 ,pp  U@  0   } P a	 X V<  0  R8  DЍ@ !Q @ P$0pD     Rp
    U@
 g @P  
@01RpBC 0  Z P  
  ,p"0 02 P , @ Pke   p@-0M  SP @        "00     , ` ,  0  R  0ЍpCTc   G-`M0Q 0 p 0 @P  
000 E
 P0 PPP0   P  Ŀ  0  R  Ѝ  Pb   H0H0@- @M  0@0  0 R  Ѝa     @-0M@ 0P   ,   
 `0   S
0`$0(   
0  ` p0 0 a ,  0 R  0ЍЀj ǿxa   A-@MP`0 P 0<0'  
p@s 0P#  
 AE 0 R0 0pB408   
  @ P0 
 , , @0n<  0 R  @Ѝj   ꌿ`   A-@MP@ P 0<0(  
p`ܿ9 0P$  
0   S 000
0 pP8 4`,00  
  ` p(0 $ a$3<  0 R  @Ѝj   Q_    C-LM@ PPh` 0D00  
pᠿ P,  
0 S%   0   R@0 0p `<$408   
0
  ` p0, 0, `0D  0 R	  LЍj %   
^   G-PMppP @ 0 `L0^  T,  
  W봾 0P(  
0 S!  t0 0   0,! P4P@04 b(P8@<@  P  `L  0 R  PЍ%   Ⱦ]   10O-TM pP  倰L X  
u PPW  
0 SN    ( @PN  
o c@2DX4!@ D υ 0   @XB    '  Q "  0!0$ D0HjP  
   0 ! < 0< @L PP  L  0  R  TЍ $0  0 寽 %PPPPZ\    0 /, /᤿A- @` Pp    HPLp⋽@0  S  U  
 5/ A聽@- @    @@x     XX O-`<R<P,M 0 $2$"  0  V $  0Q  & [ @Pi  
    Z/	=!!-  ""p/↏T"X"p ɽ  P9  l1l!	 0 ᏽ p@  
 0  S   #>0 x00  ℽ  P/  
!1 0!0$  0 R2  ,Ѝ 0  0   0 = 0   0`00 P0   0  ; Q  4dH0X % 0   0ݽ ꕽHZ   ̴D(P $  L  P    0    \881O-M4 $1     0 K`    ޽ p `  
  p m w  
 W   	A ҽ PP@   ़  P	  @   0  R  Ѝ` @p  
 T`@   ܽ0 S5W   @  ԩ  x0t 0@-M@  000000 0  0  
 0  0 R  ЍpV   0 0A-`phM  \   d	 A !AB!"8 
"B DQd  0 R  hЍU   C-Mp `P   0P
@  0    
 % p  
  p  
  p  
	0  f P ᝼  0  R  Ѝ ᔼ P꯼LU     l  00p@-XM@   P Q/0TP PA p  
   ᡾  P     P  T  0 R  XЍp0` 0H0@ 0 m  ㉾ p    s\T   0     A-P`p @ p  
0  A7  0    / <  Q    
#p@-@  P T    c  P   p0 0:   \x      10G-8M@p 0 40峻  P S0  00p, (   0 ` $`     pP  
  0   P   
E Ѽ P 4  0  R  8Ѝ P	 PR   8@p@- @P
  
A  P   i벼 P  p PG- PP(  
 @  T0  
 pw   P  
 @  T%  
= v  P  
0% S  S   0`@= S   Y   ᶽ  P
  
    P     Y  P
 ` P G- p  @P@䀟  Y `#  
	 9 	 ᧻  P   
  Z  
 ,00 0  S"  
\   U  
 \ S, S   0 00   S        P  ,0,  0   0婻   P   p  p@- @Pp   P  
0  S  
 0  S   P 0P S  0 000pA- @P`  U`  
0  S+  
 1 pP  
  H 0P  
    	   q t0t  0   0`   úD0H  0   0T  (0(( 07   $N   L    ȣ       0p@- S  @ PK pp 0 C R    p  C  B@@1C!  a煺0  `p0 0M 0    D  l   r  
 rA-`P @  
p  W  
 0 7/0 S  U  
$  A A  /@-M@4a t`(  
 P  R  0  0Ѝ  p  \
 = Q % \,   s R  
 0儻0 P  
     徻    0 p     `Ѝs  P   H0L  0   0岺  ,0,, 0 00  tL   `    @  x    O-Mġ1
0 p0 0  0Pn @PD  
   
 0  ` v/  
  ] @P1  
  Z
  
   R
   R   Q+   a ɺ    P,  

 
 g
 0  ^ ` Ἱ v0   0 R   Ѝ`	0   , `XX 0     `+,00  0   0 `-K     @    A- p ׹010 PP0@   ;  , R$  
\ R   
@   0    R    i p    `` k   Q
0A|  R   0 Br ^
   @   M p `
@ 0N~ ^!@!  $   0  ` 0  չ(I        D0D0@-M@
  00  0    R  ЍsG   C-DMRP @`     p<i  Tp  
0  S  
   X  <  0  R  DЍ(p   $0圸 p(  
 0  S 9    o \(  
- \"  0  S   ቸ p  
(080!  R $  8$   Q   - \
 0  K p 4 Ÿ      \'    R9  0  %40  S  
    p
4   p
80  S  
(  S  
 0       , 1ClQ I P ᄸ(0, 0C(04 4 0      ǸlG   @         A- P  p`2X @P
  
  0p` 0  0  ! 0   0D     p@- P$ `T00 @P	  
   `  p  !  0  0  ɸD   ,   0@-  S  0  S
    8088 03   $0$$ 04   T      4  ܚ    0  S/    R    / 0   0@-= 0  kԙ  t      Q  /  Q    / 0   0@-F 40  W넙  $  `  -  /0  S  
 /0@-   0   @ǹ0 0Y L0  6      0@-  S @  
 3/000@-  S @  
  3/ 000  S  
 / / /-M  .Ѝ-M 'Ѝ / 0    / / / / 0-   \  
 0/0/0  S   
/@- @  姸  P  -M  ➸  P   p p     `Ѝ0/@- @ᓸ0  S  
 3/ @P0@-  S @  
 3/    P   
 @B0   P/۸D 10A-MP`@  p   券  T     @岷 p  
0 X  
 @! 0  R  ލ @ @  @囷 pD  @     ␷ p @   L?   X    p@-  |@ P@  p  
    p  
    p
  
  
  p  
0  0 Pp  pB  0 0 @-  Q 0 0  
l 3  0`  0  VT@ @ z  v  r 
 @mB 8>      O-M0@  T+  
p `P   Ё  0   p  
  P  
    
 @T P p  
 0 0   p  [  
 Ѝ起   k O-M0@  T+  
P `p   Ё  0   p  
  P  
    
 @T P p  
 0 0  1 p  [  
 Ѝ肷   k O-M((4MAM@* P,  @0 ` @0JJ  U 0




 @
,  
pJ    
   0	  q  P    
 P   : PU p `
  
 @ T@! @0  	   P  X     :,0  0 0 R  ڍ4Ѝ E;   0   S  * !  R  :  
 /0 S0  
 00 /  /,0,, @-0$   @ 0 0 砒          0  \
  
      q   R0/ /3ß0O-\M
 P 08T0  
10 0(0 00 0000<0  S  *        ^$ y  * @  P`p EPH  U P! l  
  ,   
   
0   P P     
@` pd	  
H  ` pd  U@-  
0 01p4P勱 `P    Pb  
 0 10   010 W  
 pWU  
(0  0 p0 p  X4P9  
@  T2  
 1000  P	  
	 ) T @#@3  P@  Tv
@80T   0 RI  \Ѝ 0`0`0 0 P  
0 Q   *0 P.  :@  T0  S* 0 S   <   R   p0$ ,  @4P$  P0 0 @,  P0$  Z @0e @c꼴y @9    000/ 00@-@ 00@/  0/ 000/ 000/   0/ 0@-@P@@@$ 00@/  (0/  PA-  PA`  p@ l  V@  p  
` U  p O-`LL
 M  @   
P pg  @  PP k  
   0 \ 
   8 @   ,00<p    ⅵ0    S \10 H0  RL! 0L   S 8! 0P   S $! 0T   S !  0X   S   $0\   S   (0   S	0   @P0P  
0   0 R  Ѝ 
0|      h @X0\ # 0   0@j γ 4         O-|M⼂2 @ `<  0t0P    0  Rذ pE   0   S0    
WzG"{  :0  S00p  S   
 3/@  4  8 ,0   Q8 04 <0@ 0 DH ,00 @,  < , H0(     $ 0  S  
 3/ rt  0 RY  |Ѝd! 0   P!    8!0   ޴!p     մ!80   ϴ <0   ɴ @0   ô D0   㽴 H0   㷴   <0  㰴\ 0    姴zy4 \       坴 G`1     T        d    H  D  @    L  G- Ma` @pP  0@ @D p4  
l!0  ߲ p,  
PA@      ៳ P4
0	  u @   T  
 ፳ p   
ܴ P/  
 T  p  
 埴 p   ᣲ   @  0  R   Ѝx00 `   P P  ` 02   4nD 0    	 .    0      @  \  @- @p @p@-MP @@   `P 	  
0  S  ^ @  t     0 R  Ѝp聳 @꯲,    0P/  Q
  
p@- @P  u  p@谲 p A-@ P  pᾳ ` ,   A6A-M@0@ PM  R* 0  0"  p `* ὲ  P  
 ճ:0   0 R  ڍЍh00 @M  T 0    ᒳ  ,0 0    刳  M+     X  L   p@-@ R,     *         0P  0   x p@胱p0t P  0  ]\  0   dp@(808  0   K p*     `q  Ą  Ą  |  |  O-ppAp@$MP``1   T! 0  ᚱ p  
0  S  
   X  2  
  W0?o2 0  V  0  0  0 R/  $Ѝ0/  b P  
0  S
 p@ A P  
0  0 屲	  @ g t c  `404  0   0ꩱ)        n  P1P!0p@-M@  P P 00  
  0  RD  Ѝp  `P6   p P*  
  P"  0 p1  
   ઱     p `	  
ዱ ሱ ᅱ V  0  0厲 p n   !L    P `0   $   L8(   d  X        ,0, 0@-*      0}  &   Ȃ   / _ p@- Ph@`@      ᔱ P) Ʋ p @ `  
ܲ `P  
 p   p  4O-,$MPpH`   0L PT@Ͳ p&  
   P-  
X0 @0 	0% @ ǰ  T  
 s p
  
 b뼲 p  
  Z  
 ̱      # 8  y @  0  R  $Ѝ   ᡰ꽰%   -M $ ( Ѝp@-(MP8@<@    $ `P 
  
 0  S
   @  t   $  0 R  (Ѝp茲 @ꂰd$   -M  Ѝ- M PЍ-M 0P0Ѝ-M 0d0Ѝ- M PЍ-M $ ( ;Ѝ@-M @$ 0 00@d0,Ѝ-M $ ( Ѝ@- @ 廯  ί @˯@- @@ 倱 A- `P _qp @PB  
x1x! 0 ᮯ p  
   X  
0  S   `  V:  
 ᝰ 0  S  
 00S/ S  1 0H  u  P  呯 Ꮿ  0 2 0   0  `P  
 `v0000  p x0 & 0   0 P0\ % 0   0,0< & 0   0!       }  ]  ,}  `}  |  <0  R0  
 /( @-  0  0  ٯ  <    |  A- PR`  
   p,0   @P  
 0  / SPʯ ǯ 0  S.00 @  @ 00A-MP @p 00V 
0@  `P  
  0  R
  Ѝ0   剰 `  Ih   00C-PM @  p @. 0@  `P  
  0  R
  Ѝ 0؃ ᫮ ` ̮   G-Mp @` 0P08 0@ w P  
  0	  R  Ѝ  `偰  塮    00A-MP @p 00ٮ 
0@ O `P  
  0  R
  Ѝ0   彰 `  z̮t   00@-MP @p 00峮 
0@ ) `P  
  0  R	  Ѝ   ޯ `  Uꧮ   C-MP @ 0p0ዮ 0@  `P  
  0  R  Ѝ 	0  夰 ` +}D   00A-MP @p 00c 
0@  `P  
  0  R
  Ѝ0   ' `  V   C-PpM0 0 `@00: 0`  P  
  0  R  Ѝ  0 *  ڭ,    00A-MP @p 00 
0@  `P  
  0  R
  Ѝ0   L `  峭X   00@-MP @p 00 
0@ b `P  
  0  R	  Ѝ    `  厭   00A-MP @p 00ƭ 
0@ < `P  
  0  R
  Ѝ0   t `  g깭(   00@-MP @p 00堭 
0@  `P  
  0  R	  Ѝ   w `  Bꔭ   00C-PM @  p @y 0@  `P  
  0  R
  Ѝ 0؃ H ` i   00@-MP @p 00P 
0@  `P  
  0  R	  Ѝ    `  DL   00@-MP @p 00+ 
0@  `P  
  0  R	  Ѝ   
 `  ͬ   00A-MP @p 00 
0@ { `P  
  0  R
  Ѝ0   巭 `  妬$   C-MP @ 0p0ܬ 0@ R `P  
  0  R  Ѝ 	0  ) ` |ά   C-MP @ 0p0Წ 0@ ( `P  
  0  R
  Ѝ0  	0   . ` Pꢬ   00A-MP @p 00刬 
0@  `P  
  0  R
  Ѝ0   [ `  ){0   00@-MP @p 00b 
0@  `P  
  0  R	  Ѝ    `  V   00@-MP @p 00= 
0@  `P  
  0  R	  Ѝ   
 `  ߫1    00@-MP @p 00 
0@  `P  
  0  R	  Ѝ    `  庫l   00@-MP @p 00 
0@ i `P  
  0  R	  Ѝ    `  啫   A-PpM0 0 `@0̫ 
0` B P  
  0  R
  Ѝ 0     m꿫D   00A-MP @p 00奫 
0@  `P  
  0  R
  Ѝ0   ! `  Fꘫ   00@-MP @p 00 
0@  `P  
  0  R	  Ѝ   o `  !s   00A-MP @p 00Z 0@  `P  
  0  R  Ѝ 0  `P  
   鬫 ` Dt   00A-MP @p 00+ 0@  `P  
  0  R  Ѝ 0  `P  
 ʪ  鶫 ` ê   00@-MP@ p 00 
0@ r `P  
  0  R	  Ѝ    `  垪
   |0|0p@-MP @ 00ت 
0@ N `P  
  0  R  Ѝp  冫 `  {ͪh
   |0|0p@-MP @ 00嵪 
0@ + `P  
  0  R  Ѝp   `  Xꪪ   00@-MP @p 00呪 
0@  `P  
  0  R	  Ѝ   奪 `  3ꅪP   C-Mp @` 0P0i 0@  P  
  0	  R
  Ѝ  ``  
\   20O-M` @ 00B 0P  pP  
  0  R  Ѝ	0  ũ pP0  0  S-  
 0/ S*   0 / Q&   0
 P/ Q#  
/ SB  @/ T
 T#    T=  
     S  
/ S  
 P0 S
  S  
  \/ S+  / 0 
 ᰩP/ \  
PK0 Q  T P
/ T  
@  T/ T   @/ T
  T0  
P 0 @P0K Q }00 Y:  P0    U @  
d  0  0 S   `  U깩       Xf  f  00@-MP @p 00噩 
0@  `P  
  0  R	  Ѝ    `  ;ꍩp   O-4M `Q   , F  
 P p a    @PP  
0 0$`(@&( $(0  W$ 
   0	˨ p  
 妨(  0` 00 @0,   0 R/  4Ѝ8 0 S   0 01`0[  P  
( $0@B@0(@$0 @0 `S` 0$  W(   0 ᔨ q Ҩ``    00A-M@ Pp 00 0
 `  PP  
  0  R
  Ѝ0    9 P  姨(   00p@-M@ P`    0 \  P P  "  	 3/ P 刨  0  R  ЍpԨ   00C-@M P  p @幨 0 ` 3 PP  
  0  R
  Ѝ  0؃ 6 P Wꩨ   G-Mp @` 0P08匨 0 	  @P  
  0  R  Ѝ   ` @ ,~L   00A-M@ Pp 00d 0
 `  PP  
  0  R
  Ѝ0    H P  W   0 0@-M@ Pp 00> 0
 `  PP  
  0  R	  Ѝ    i P  2   C-M@ P 0p0 0 `  PP  
  0  R  Ѝ  	0  / P 嶧p   00A-M@ Pp 00 0
 ` h PP  
  0  R
  Ѝ0    岨 P  叧   C-MP`0 p 0@00ŧ 0  ? pP  
  0  R  Ѝ   0 嵨 p e귧,   00A-M@ Pp 00坧 0
 `  PP  
  0  R
  Ѝ0    ק P  >ꐧ    0 0@-M@ Pp 00w 0
 `  PP  
  0  R	  Ѝ    卨 P  k   @- @  $ ʦ( Ȧ  	   @@- @I@  幨 00A-M@ Pp 007 0
 `  PP  
  0  R
  Ѝ0     P  ئ*   0 0@-M@ Pp 00 0
 `  PP  
  0  R	  Ѝ     P  峦P   00C-@,M P  p$ P 0 P d `P  
$  0  R  ,Ѝ$   400 Pp 嵨 ` 儦֦   0 0@-M@ Pp 00弦 0
 ` 6 PP  
  0  R	  Ѝ    h P  ^갦   0 0@-M@ Pp 00嗦 0
 `  PP  
  0  R	  Ѝ    v P  9ꋦh   00A-M@ Pp 00q 0
 `  PP  
  0  R
  Ѝ0    # P  d   C-M@ P 0p0H 0 `  PP  
  0  R  Ѝ  	0  啧 P :8   C-M@ P 0p0 0 `  PP  
  0  R
  Ѝ0   	0   嚦 P 弥   00A-M@ Pp 00 0
 ` n PP  
  0  R
  Ѝ0    Ǧ P  啥   0 0@-M@ Pp 00Υ 0
 ` H PP  
  0  R	  Ѝ    Z P  p¥D   0 0@-M@ Pp 00婥 0
 ` # PP  
  0  R	  Ѝ    v P  Kꝥ   0 0@-M@ Pp 00儥 0
 `  PP  
  0  R	  Ѝ    Y P  &x   0 0@-M@ Pp 00_ 0
 `  PP  
  0  R	  Ѝ    c P  S   A-MP`0 p 0@08 0
   pP  
  0  R
  Ѝ 0   ] p  ٤+   00A-M@ Pp 00 0
 `  PP  
  0  R
  Ѝ0    卥 P  岤T   0 0@-M@ Pp 00 0
 ` e PP  
  0  R	  Ѝ    ۤ P  卤ߤ   0 0@-M@ Pp 00Ƥ 0 ` @ PP  
  0  R  Ѝ0  2 PP  
 f    P _걤$   0 0@-M@ Pp 00嘤 0 `  PP  
  0  R  Ѝ0   PP  
 8   $ P 1ꃤl   0 0@-M@ Pp 00j 0 `  PP  
  0  R  Ѝ0   PP  
 
   f P U   |0| 0p@-M@ P 00= 0
 `  PP  
  0  R  Ѝp    P  2   |0| 0p@-M@ P 00 0
 `  PP  
  0  R  Ѝp    P  彣p   0 0@-M@ Pp 00 0
 ` p PP  
  0  R	  Ѝ    
 P  嘣   C-Mp @` 0P0Σ 0 	 H @P  
  0  R
  Ѝ   `Ť @ oP   00A-M@ Pp 00姣 0 ` ! PP  
  0  R  Ѝ0   * PP  
 G 0 	 PP`H  ᛤP 6ꈣ   0 0@-M@ Pp 00o 0
 `  PP  
  0  R	  Ѝ     P  c   C- pMP ,㩢b` @PX  
2" 0  p
  
 0  S  
0  S  
11 0   0儣      Ѝ  Y2  
   X&  
 0  S p$  
	 ᤣ p$ 2  
	 ឣ$0 s( B  
  W  
  㔤 Ģ$ 0   0<  㜤  P( s$ q  쀟  } pА	0 % 0   0:  0     " 唢  咢 ᐢ  W
  Y ቢ,H 	0      ,  <j   L  Li \H  PH  XK  DK  |K   K  A- PRx@@  
 h 5봢 p [밢 ` , \00 0     R   0G    J  O-sßpM PP 00X  
 00  㬢 p @J  

 p `X  
  P_  
P0 匤 00000000 00080$004(0  Z 0 S:    
 ( p @
  P!  
(0 S  $ 0 S@   P  U  
  0  Rj  Ѝ4 Z  ᗢ! @    { @  s1# 0   0 @xx  el@  `0 24 0  [:  D1  Z0800  
01@0<00 !    @4 P@ 0 x 0
0@         ਢ 8@  Ģ   ໡   ! 㭡 t   V p @
  00 (     hJ  I  I  8J  I  I  1  @  I  H  H  H  H  B  C-`$B$@MP p  R}  =  A  D  G  J  M       *  a `ԑ 	     PP  
  P1刀0 0  Q     0 RF  Ѝh1hh!0   0Ρ   0P7  
 s  
  ɡ    0 آ, ⋣$ Т( ̢0 0Ƣ p
0 ௠ p     `x0 , 0   0咡PKl0@0  X   P         8H  d dd    H    dG  G   G  F   ,F  E  `1`!0@-,M@ `P 0$0  
 qP  
 0 
 0 PP p  W  
D  P  
 {  P  
 p 0  
  P  
  L$  0 R  ,Ѝ 0   w 0 #  Pp p   h@hh h P @   0 `@娡 ᠠ 㕠\    ,  G  dG  |D  dG  <  D   h0h 0p@-8M@ P` 4  
 4  0 4  0 R  8Ѝp誠   O-UMW7P ,p@ 0 ` 4 L1(埡0  T80  
P'P7   04 p @  
,0  S  
00  S  40  S @  
( (H &L $X "P  \ T L! 0  R Uߍ8p   
F(@  Q  
0  S
0 
 ὡ p @\  Q  
( ⴡ p
T  Q  
( ⭡ p
(0  V$0i 
`0  0. p @j 
<0  S|  
@0  S  up ᠠ p @: 
ppƟz "%0 p   5\ ~ p  g  
Hp  W)  
 ᵠ)L  [  
 ᯠ 	    |  Y  P   
D0  S     [  
.0 0  W p>	 ;\ 80   	  p   
  Pk  tp   PP  
$0  0 0	C  p { wX   9 t	 r Ρl,4,D 0   0 @:Љp   3  p @x/ ᶡ @+(  p=L M	 K ᧡X  Q  
(  p@
L0(  S  
 P `P pk  
 P pf  
@p0`   @` ) t0 (  @ 	  t
n  Wrp u	 ܟ   [J p   W
  
 W
2 0 P֟"  0 ᇠL0  ST  
DH   Q@  
X2  R0  L  
\ 80   	 b pT 0 0 S
D C  Q/o"    Rp
   P1  0   0eT` ɞ1  0   0Y ᾞ	 ἞  @  @g @`  R   
  
 0D1 0 	 0	 ?ٟ00 P   P P   02   'ba 0    Y0 # 0   0 @OX00 P崟  I| 0    A꿞H   (` t_ D  LE  (  '    B  &   @  A  A  B  @  A  DA  4$  @  ?  @  ;  T?  O- p0R0POM 4@  ,  4``    , p6  
	 p @$  
  P?  
  0̞ p @  
00  S @   ,04!  0 RY  Oߍd10 PU  P!0    ᚟,10 PG  ܞ!0    ጟ0 @0 P8  ͞ 0    }   0@ߝq0 0  000  0 0  @0婟@00 @  塞P 0    Q 㤞@     T@  ?  h?  6  t?  D?  !   ?  ?  ?  G-FM(R(2P@`   01pw u   㓝 p5  
p p @#  
  P>  
  3 p @
  
0  S @   ~! 0  RQ  Fߍp10 P彞  R\!0    810 P寞  D(!0     1 @0 P堞  5 0       @GٝR  Z  
       @	0  l00 @|  p 0     놝 H D  	0       =  \=  =  \=  <=  <  =  <  `<  C-GMQ1P@`   01pޞ ܝ    p5  
מ p @#  
  P>  
  ⚝ p @
  
0  S @   ! 0  RQ  GߍD10 P$  幝0!0    i10 P  嫝 0    [0 @0 P  圝 0    L   @宜@빞00 000| |0  @0倞@00 @  xH 0    ( {d     ;  :  :  ,;  :  t:  h:  :  818!0@-tM@ p$a 0`l0{   P Ϟ  P  0/ S  
P
 P Ӟ p  
0:

S	  
\ `P    p  
P    Pl  0  R  tЍ藝 PPUP꒝ PPUP   a ܝ pP   PPUP  T꒜8   p:  4:  A- P @`p  P0  AA- M Pp@``  P
    T ۜ p @  
 Ѝ  ЍAV@00 `F  ۜ,  P0   ኝ Ѝ   t8  p@- P @d  Pp p@O-Mb2`M P* 0   Up  0~  
 ) @P  
ќ @ 0 T    :C   s T@  
/ R
   / ᫝ Pc  
 TPy  
,	   P/  
	 y  P)  
  [ 0 00 *0H  P$  
 ᡜ p	 វ   n PPK  
  W  
0p0W/ SS  
1 0   ՜ Ꮫ  / RP* #  P  D1 P0 `徜  S,! p
0    t:0   0  R4  ڍЍ ᶛ P e  U  PP  0  p    R t
0   P  ՜dPP\0 0  ゜@  
0 ꋛ   x/  7  H7    6  -  5  5  
  5  5  G-*	RM 	  
"0    Ѝ ڛ `P)  
pp  PP@   
͚  P 
Ț  P
 m 
0@   凜| 
0   ぜ   [ Ѝ@00 @(  彛4 
0    m   ,  5    $5  (5  4  0 0A-BM  0  1 `P   
|p@p   g  P     PP X ! 0 R  Bߍ O `     4  4   Q/t  : Pk   l  
?o/o0B0s0    P @ P @ P @ P @ 
P 
@ 
P 
@ P @ P @ P @ P @ 
P 
@ 
P 
@ 	P 	@ 	P 	@ P @ P @ P @ P @ P @ P @ P @ P @ P @ P @ P @ P @ P @ P @ P @ P @  P  @  P  @  /   //o b0/  P  K    Q
@-@ A/  S  R    Q      P  8  M `-  Q    S  5  Ѝ /  p  S  ,  Ѝ   p  r0/  r0!  Ѝ   p/  r0  Ѝ   r0/  S  R    Q  P     M `-  Ѝ /@- ㈙ Q PO- @  3P$ 1=  :  Soo   Uo oL L l2	 U T  3 1  : @T0	P  \!  
`op   0T0@ P R  
 U T*@P R4<;5,5: @<:̠4; PP  ^@@-fuse_put_module unlock_path try_get_path    unref_node  delete_node unlink_node forget_node fuse_clean_cache    fuse_do_release fuse_fs_write_buf   fuse_lib_ioctl  fuse_destroy    fuse_lib_help_modules       -o hard_remove         immediate removal (don't hide files)
    -o use_ino             let filesystem set inode numbers
    -o readdir_ino         try to fill in d_ino in readdir
    -o direct_io           use direct I/O
    -o kernel_cache        cache files in kernel
    -o [no]auto_cache      enable caching based on modification times (off)
    -o umask=M             set file permissions (octal)
    -o uid=N               set file owner
    -o gid=N               set file group
    -o entry_timeout=T     cache timeout for names (1.0s)
    -o negative_timeout=T  cache timeout for deleted names (0.0s)
    -o attr_timeout=T      cache timeout for attributes (1.0s)
    -o ac_attr_timeout=T   auto cache timeout for attributes (attr_timeout)
    -o noforget            never forget cached inodes
    -o remember=T          remember cached inodes for T seconds (0s)
    -o nopath              don't supply path if not necessary
    -o intr                allow requests to be interrupted
    -o intr_signal=NUM     signal to send on interrupt (%i)
    -o modules=M1[:M2...]  names of modules to push onto filesystem stack

   fuse.c  m->ctr > 0  so->ctr > 0 fuse: clock_gettime fuse internal error: node %llu not found
   wnode->treelock == TREELOCK_WRITE   node->treelock != 0 node->treelock != TREELOCK_WAIT_OFFSET  node->treelock != TREELOCK_WRITE    need_lock   /   fuse warning: munmap(%p) failed
    node->refctr > 0    DELETE: %llu
   node->treelock == 0 fuse internal error: unable to unhash node: %llu
   node->nlookup > 1   fuse: hidden file got created during hiding
    fuse: failed to allocate thread specific data
  %s %li
 %s %li (w)
 QUEUE PATH  DEQUEUE PATH    QUEUE PATH1       PATH2 DEQUEUE PATH1           PATH2   QUEUE PATH (forget) DEQUEUE_PATH (forget)   node->nlookup >= nlookup    FORGET %llu/%llu
   node->nlookup == 1  fuse: failed to allocate read buffer
   fuse: failed to allocate cmd
   getattr %s
 fgetattr[%llu] %s
     NODEID: %lu
 LOOKUP-DOT
 LOOKUP-DOTDOT
  LOOKUP %s
  rename %s %s
   .fuse_hidden%08x%08x    unlink %s
  rmdir %s
   symlink %s %s
  link %s %s
 +flush  release%s[%llu] flags: 0x%x
    -   node->open_count > 0    opendir flags: 0x%x %s
    opendir[%lli] flags: 0x%x %s
    open flags: 0x%x %s
       open[%lli] flags: 0x%x %s
   read[%llu] %zu bytes from %llu flags: 0x%x
    read[%llu] %zu bytes from %llu
  fuse: read too many bytes
  page    buf->idx == 0 && buf->off == 0  write%s[%llu] %zu bytes to %llu flags: 0x%x
       write%s[%llu] %u bytes to %llu
  fuse: wrote too many bytes
 fsync[%llu] datasync: %i
   fsyncdir[%llu] datasync: %i
    flush[%llu]
    statfs %s
  releasedir[%llu] flags: 0x%x
   readdir[%llu] from %llu
    getdir[%llu]
   create flags: 0x%x %s 0%o umask=0%03o
     create[%llu] flags: 0x%x %s
 F_SETLK F_SETLKW    F_GETLK ??? F_RDLCK F_WRLCK F_UNLCK lock[%llu] %s %s start: %llu len: %llu pid: %llu
   LOCK_EX LOCK_UN LOCK_SH |LOCK_NB    lock[%llu] %s%s
    chown %s %lu %lu
   truncate %s %llu
   ftruncate[%llu] %llu
   utimens %s %li.%09lu %li.%09lu
 utime %s %li %li
   access %s 0%o
  readlink %s %lu
    mknod %s 0%o 0x%llx umask=0%03o
    mkdir %s 0%o umask=0%03o
   setxattr %s %s %lu 0x%x
    getxattr %s %s %lu
 listxattr %s %lu
   bmap %s blocksize: %lu index: %llu
 removexattr %s %s
  ioctl[%llu] 0x%x flags: 0x%x
   !in_bufsz || !out_bufsz || in_bufsz == out_bufsz    poll[%llu] ph: %p
     poll[%llu] revents: 0x%x
    fallocate %s mode %x, offset: %llu, length: %llu
   fuse: warning: library too old, some operations may not not work
   fuse: failed to allocate fuse_fs object
    list_empty(&f->partial_slabs)   list_empty(&f->full_slabs)  fuse: failed to create thread specific key: %s
 fuse: failed to allocate fuse object
   fuse: memory allocation failed
 libfusemod_%s.so    fuse: dlopen() failed: %s
  fuse    fuse_fusemod_%s_module  fuse: %s did not register any modules
  fuse: dlclose() failed: %s
 
Module options:
   -h  
[%s]
  newfs == NULL   nullpath_ok: %i
    nopath: %i
 utime_omit_ok: %i
  fuse: cannot get old signal handler fuse: cannot set interrupt signal handler   -o  debug   --help  -d  hard_remove use_ino readdir_ino direct_io   kernel_cache    auto_cache  noauto_cache    umask=  umask=%o    uid=    uid=%d  gid=    gid=%d  entry_timeout=%lf   attr_timeout=%lf    ac_attr_timeout=%lf ac_attr_timeout=    negative_timeout=%lf    noforget    remember=%u nopath  intr    intr_signal=%d  modules=%s  fuse_kern_chan_receive  fuse_kern_chan_send fuse_kern_chan.c    se != NULL  fuse: reading device    short read on fuse device
  fuse: writing device    FUSE_THREAD_STACK   fuse: invalid stack size: %s
   fuse: error creating thread: %s
    fuse: failed to allocate worker structure
                                  P                   do_write_buf        -o max_write=N         set maximum size of write requests
    -o max_readahead=N     set maximum readahead
    -o max_background=N    set number of maximum background requests
    -o congestion_threshold=N  set kernel's congestion threshold
    -o async_read          perform reads asynchronously (default)
    -o sync_read           perform reads synchronously
    -o atomic_o_trunc      enable atomic open+truncate support
    -o big_writes          enable larger than 4kB writes
    -o no_remote_lock      disable remote file locking
    -o no_remote_flock     disable remote file locking (BSD)
    -o no_remote_posix_lock disable remove file locking (POSIX)
    -o [no_]splice_write   use splice to write to the fuse device
    -o [no_]splice_move    move data while splicing to the fuse device
    -o [no_]splice_read    use splice to read from the fuse device
  using FUSE kernel interface version %i.%i
  fuse: unknown option `%s'
  INTERRUPT: %llu
    NOTIFY: code=%d length=%u
     unique: %llu, error: %i (%s), outsize: %i
      unique: %llu, success, outsize: %i
  fuse: copy from pipe: %s
   fuse: copy from pipe: short read
   fuse: internal error: failed to read back from pipe: %s
    fuse: internal error: short read back from pipe: %i from %zi
   fuse: failed to allocate request
   fuse: short vmsplice to pipe: %u/%zu
      unique: %llu, success, outsize: %i (splice)
 fuse: splice from pipe  fuse: short splice from pipe: %u/%u
    fuse: splice from device    short splice from fuse device
  fuse: bad error value: %i
  flags=0x%08x
   max_readahead=0x%08x
   fuse: unsupported protocol version: %u.%u
  fuse: warning: buffer size too small: %zu
     INIT: %u.%u
    flags=0x%08x
       max_readahead=0x%08x
       max_write=0x%08x
       max_background=%i
      congestion_threshold=%i
 fuse: failed to allocate header
    unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu, pid: %u
   fuse_lowlevel.c !(bufv.buf[0].flags & FUSE_BUF_IS_FD)   fuse: do_write_buf: buffer size too small
  fuse: retrieve reply: buffer size too small
    fuse: warning: library too old, some operations may not work
   2.9.9   FUSE library version: %s
   /proc/%lu/task/%lu/status   
Groups:    -osync_read -omax_readahead=%u  max_read=   max_read=%u allow_root  max_write=%u    max_readahead=%u    max_background=%u   congestion_threshold=%u async_read  sync_read   atomic_o_trunc  no_remote_lock  no_remote_flock no_remote_posix_lock    big_writes  splice_write    no_splice_write splice_move no_splice_move  splice_read no_splice_read  -V  --version   LOOKUP  FORGET  GETATTR SETATTR READLINK    SYMLINK MKNOD   MKDIR   UNLINK  RMDIR   RENAME  OPEN    READ    STATFS  RELEASE FSYNC   SETXATTR    GETXATTR    LISTXATTR   REMOVEXATTR FLUSH   INIT    OPENDIR READDIR RELEASEDIR  FSYNCDIR    GETLK   SETLK   SETLKW  ACCESS  CREATE  INTERRUPT   BMAP    DESTROY IOCTL   POLL    NOTIFY_REPLY    BATCH_FORGET    FALLOCATE   CUSE_INIT   mt_chan_receive fuse_mt.c   size >= sizeof(cmd) fuse_opt_add_arg    fuse_opt_insert_arg_common  process_opt_param   fuse_opt.c  !args->argv || args->allocated  pos <= args->argc   format[0] == '%'    fuse: invalid parameter in option `%s'
 fuse: missing argument after `%s'
  --  fuse_session_add_chan   fuse_session_remove_chan    fuse_session_next_chan  fuse_session_process_buf    fuse: failed to allocate channel
   fuse: failed to allocate session
   fuse_session.c  se->ch == NULL  ch->se == NULL  se->ch == ch    ch == NULL || ch == se->ch  !(buf->flags & FUSE_BUF_IS_FD)  fuse: cannot set signal handler fuse: fuse_remove_signal_handlers: unknown session
 fuse_bufvec_advance buffer.c    bufv->off <= buf->size  cuse: dev_info (%zu) too large, limit=%u
   cuse: failed to allocate cuse_data
 CUSE_INIT: %u.%u
   cuse: unsupported protocol version: %u.%u
  cuse: warning: buffer size too small: %zu
     CUSE_INIT: %u.%u
       max_read=0x%08x
    dev_major=%u
       dev_minor=%u
       dev_info: %.*s
  /dev/null   /dev/cuse   cuse: device not found, try 'modprobe cuse' first
  cuse: failed to open %s: %s
    subtype=    fuse: bad mount point `%s': %s
 fuse: invalid argument `%s'
    usage: %s mountpoint [options]

    general options:
    -o opt,[opt...]        mount options
    -h   --help            print help
    -V   --version         print version

  FUSE options:
    -d   -o debug          enable debug output (implies -f)
    -f                     foreground operation
    -s                     disable multi-threaded operation

 -osubtype=%s    fuse_daemonize: pipe    fuse_daemonize: fork    fuse_daemonize: setsid  fuse_main(): This function does not exist
  -f  -s  fsname= -ho fuse-subdir: memory allocation failed
  fuse-subdir: exactly one next filesystem required
  fuse-subdir: missing 'subdir' option
       -o subdir=DIR	    prepend this directory to all paths (mandatory)
    -o [no]rellinks	    transform absolute symlinks to relative
  .   ../ subdir  subdir=%s   rellinks    norellinks  UTF-8   fuse-iconv: memory allocation failed
   fuse-iconv: exactly one next filesystem required
   fuse-iconv: cannot convert from %s to %s
       -o from_code=CHARSET   original encoding of file names (default: UTF-8)
    -o to_code=CHARSET	    new encoding of the file names (default: %s)
    iconv   from_code=%s    to_code=%s  fuse: missing mountpoint parameter
 fuse: socketpair() failed   fuse: fork() failed fusermount  %i  _FUSE_COMMFD    /bin/fusermount fuse: failed to exec fusermount got control message of unknown type %d
 recvmsg ro  rw  allow_other -oallow_root    fuse: internal error, can't find mount flag
        -o allow_other         allow access to other users
    -o allow_root          allow access to root
    -o auto_unmount        auto unmount on process termination
    -o nonempty            allow mounts over non-empty file/dir
    -o default_permissions enable permission checking by kernel
    -o fsname=NAME         set filesystem name
    -o subtype=NAME        set filesystem type
    -o large_read          issue large read requests (2.4 only)
    -o max_read=N          set maximum size of read requests

  -u  -q  -z  fuseblk /dev/fuse   fuse: 'allow_other' and 'allow_root' options are mutually exclusive
    fuse: failed to access mountpoint %s: %s
   fuse: device not found, try 'modprobe fuse' first
  fuse: failed to open %s: %s
    fd=%i,rootmode=%o,user_id=%u,group_id=%u    fuse: failed to allocate memory
    %s#%s   fuse: 'fuseblk' support missing
    fuse: mount failed: %s
 suid    nosuid  dev nodev   exec    noexec  async   sync    atime   noatime dirsync nonempty    blkdev  auto_unmount    fsname=%s   subtype=%s  large_read  blksize=    default_permissions fscontext=  defcontext= rootcontext=    user=   -r  %s: sigprocmask: %s
    %s: fork: %s
   -i  --no-canonicalize   /bin/mount  -t  %s: failed to execute /bin/mount: %s
   %s: waitpid: %s
    /bin/umount -l  %s: failed to execute /bin/umount: %s
  --fake  /etc/mtab   %s: failed to unmount %s: %s
   %s: invalid mountpoint '%s'
    %s: failed to allocate memory
  ..  %s: bad mount point %s: %s
 %s%s    %s/%s   %s: failed to open mountpoint for reading: %s
  %s: mountpoint is not empty
    %s: if you are sure this is safe, use the 'nonempty' mount option
  /proc/filesystems   fuseblk
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           ,T  R  S               <       <       @       D       H       X       \       `       `        L               P                T              $        8         L (       ` 0      t         4    4        8       d       h        p                       h    ̍        |  D      0  \  <        `  $  ܬ      4    4  `    l      0    <    4  |        <  D  d                                 (        <        P       h       t                                                          $                (                 ,                 ,     0                                                                          L       P        T                        \    ,     0       T                        |	         	       	                    | Ԡ     0     4 x  H                 X   d ȕ 4   ` Ē   0   P   x            ̍                  
        
                    $ @       |  8  ȶ 4       d         г <   \     0    ܬ   h  $ |  L              ĥ                                                                                                                                                                                         T        $    0    <    l    P    \    h         x                                                                                 ,     0                         3 <  = D  82 L  1 T  0 \  0 h          80 p  / x  /   /   T/   / `  B   P.   p- h D   ,           +   x+   H+   (+   +   L*   l$    B   #  $#  t"  ! ( ! 0 ! 8 l  @  H  P x \  d ` l t t    | =                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    y     1     B     R     \     p     DG  
       !          !       o8            
                             ?     t4              o\2  o
         o   o3  o   o/  o^                                          ܪ         PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG  PG                      (                 t	              
              @ 0      A,   aeabi "   6 	
"   d4a4b321ab69af9aeef3db322ba67396f4d52b.debug    Ǘ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.version_r .rel.dyn .rel.plt .init .text .fini .rodata .ARM.exidx .eh_frame .init_array .fini_array .data.rel.ro .dynamic .got .data .bss .ARM.attributes .gnu_debuglink                                                         $                     o   8  8  X               (                            0                              8   o   /  /                 E   o   \2  \2  X     
          T   o   3  3                  c   	      t4  t4                  l   	   B   ?  ?                u         DG  DG                    p         PG  PG                  {         R  R                                                          /                      p                                                            ! !                           ! !                           ! !                           ܪ ܪ                                                         H                           H H 8                       p        H -                                x 4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          /**
 * The `node:crypto` module provides cryptographic functionality that includes a
 * set of wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign, and verify
 * functions.
 *
 * ```js
 * const { createHmac } = await import('node:crypto');
 *
 * const secret = 'abcdefg';
 * const hash = createHmac('sha256', secret)
 *                .update('I love cupcakes')
 *                .digest('hex');
 * console.log(hash);
 * // Prints:
 * //   c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e
 * ```
 * @see [source](https://github.com/nodejs/node/blob/v22.x/lib/crypto.js)
 */
declare module "crypto" {
    import * as stream from "node:stream";
    import { PeerCertificate } from "node:tls";
    /**
     * SPKAC is a Certificate Signing Request mechanism originally implemented by
     * Netscape and was specified formally as part of HTML5's `keygen` element.
     *
     * `<keygen>` is deprecated since [HTML 5.2](https://www.w3.org/TR/html52/changes.html#features-removed) and new projects
     * should not use this element anymore.
     *
     * The `node:crypto` module provides the `Certificate` class for working with SPKAC
     * data. The most common usage is handling output generated by the HTML5 `<keygen>` element. Node.js uses [OpenSSL's SPKAC
     * implementation](https://www.openssl.org/docs/man3.0/man1/openssl-spkac.html) internally.
     * @since v0.11.8
     */
    class Certificate {
        /**
         * ```js
         * const { Certificate } = await import('node:crypto');
         * const spkac = getSpkacSomehow();
         * const challenge = Certificate.exportChallenge(spkac);
         * console.log(challenge.toString('utf8'));
         * // Prints: the challenge as a UTF8 string
         * ```
         * @since v9.0.0
         * @param encoding The `encoding` of the `spkac` string.
         * @return The challenge component of the `spkac` data structure, which includes a public key and a challenge.
         */
        static exportChallenge(spkac: BinaryLike): Buffer;
        /**
         * ```js
         * const { Certificate } = await import('node:crypto');
         * const spkac = getSpkacSomehow();
         * const publicKey = Certificate.exportPublicKey(spkac);
         * console.log(publicKey);
         * // Prints: the public key as <Buffer ...>
         * ```
         * @since v9.0.0
         * @param encoding The `encoding` of the `spkac` string.
         * @return The public key component of the `spkac` data structure, which includes a public key and a challenge.
         */
        static exportPublicKey(spkac: BinaryLike, encoding?: string): Buffer;
        /**
         * ```js
         * import { Buffer } from 'node:buffer';
         * const { Certificate } = await import('node:crypto');
         *
         * const spkac = getSpkacSomehow();
         * console.log(Certificate.verifySpkac(Buffer.from(spkac)));
         * // Prints: true or false
         * ```
         * @since v9.0.0
         * @param encoding The `encoding` of the `spkac` string.
         * @return `true` if the given `spkac` data structure is valid, `false` otherwise.
         */
        static verifySpkac(spkac: NodeJS.ArrayBufferView): boolean;
        /**
         * @deprecated
         * @param spkac
         * @returns The challenge component of the `spkac` data structure,
         * which includes a public key and a challenge.
         */
        exportChallenge(spkac: BinaryLike): Buffer;
        /**
         * @deprecated
         * @param spkac
         * @param encoding The encoding of the spkac string.
         * @returns The public key component of the `spkac` data structure,
         * which includes a public key and a challenge.
         */
        exportPublicKey(spkac: BinaryLike, encoding?: string): Buffer;
        /**
         * @deprecated
         * @param spkac
         * @returns `true` if the given `spkac` data structure is valid,
         * `false` otherwise.
         */
        verifySpkac(spkac: NodeJS.ArrayBufferView): boolean;
    }
    namespace constants {
        // https://nodejs.org/dist/latest-v22.x/docs/api/crypto.html#crypto-constants
        const OPENSSL_VERSION_NUMBER: number;
        /** Applies multiple bug workarounds within OpenSSL. See https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_options.html for detail. */
        const SSL_OP_ALL: number;
        /** Instructs OpenSSL to allow a non-[EC]DHE-based key exchange mode for TLS v1.3 */
        const SSL_OP_ALLOW_NO_DHE_KEX: number;
        /** Allows legacy insecure renegotiation between OpenSSL and unpatched clients or servers. See https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_options.html. */
        const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number;
        /** Attempts to use the server's preferences instead of the client's when selecting a cipher. See https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_options.html. */
        const SSL_OP_CIPHER_SERVER_PREFERENCE: number;
        /** Instructs OpenSSL to use Cisco's version identifier of DTLS_BAD_VER. */
        const SSL_OP_CISCO_ANYCONNECT: number;
        /** Instructs OpenSSL to turn on cookie exchange. */
        const SSL_OP_COOKIE_EXCHANGE: number;
        /** Instructs OpenSSL to add server-hello extension from an early version of the cryptopro draft. */
        const SSL_OP_CRYPTOPRO_TLSEXT_BUG: number;
        /** Instructs OpenSSL to disable a SSL 3.0/TLS 1.0 vulnerability workaround added in OpenSSL 0.9.6d. */
        const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number;
        /** Allows initial connection to servers that do not support RI. */
        const SSL_OP_LEGACY_SERVER_CONNECT: number;
        /** Instructs OpenSSL to disable support for SSL/TLS compression. */
        const SSL_OP_NO_COMPRESSION: number;
        /** Instructs OpenSSL to disable encrypt-then-MAC. */
        const SSL_OP_NO_ENCRYPT_THEN_MAC: number;
        const SSL_OP_NO_QUERY_MTU: number;
        /** Instructs OpenSSL to disable renegotiation. */
        const SSL_OP_NO_RENEGOTIATION: number;
        /** Instructs OpenSSL to always start a new session when performing renegotiation. */
        const SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number;
        /** Instructs OpenSSL to turn off SSL v2 */
        const SSL_OP_NO_SSLv2: number;
        /** Instructs OpenSSL to turn off SSL v3 */
        const SSL_OP_NO_SSLv3: number;
        /** Instructs OpenSSL to disable use of RFC4507bis tickets. */
        const SSL_OP_NO_TICKET: number;
        /** Instructs OpenSSL to turn off TLS v1 */
        const SSL_OP_NO_TLSv1: number;
        /** Instructs OpenSSL to turn off TLS v1.1 */
        const SSL_OP_NO_TLSv1_1: number;
        /** Instructs OpenSSL to turn off TLS v1.2 */
        const SSL_OP_NO_TLSv1_2: number;
        /** Instructs OpenSSL to turn off TLS v1.3 */
        const SSL_OP_NO_TLSv1_3: number;
        /** Instructs OpenSSL server to prioritize ChaCha20-Poly1305 when the client does. This option has no effect if `SSL_OP_CIPHER_SERVER_PREFERENCE` is not enabled. */
        const SSL_OP_PRIORITIZE_CHACHA: number;
        /** Instructs OpenSSL to disable version rollback attack detection. */
        const SSL_OP_TLS_ROLLBACK_BUG: number;
        const ENGINE_METHOD_RSA: number;
        const ENGINE_METHOD_DSA: number;
        const ENGINE_METHOD_DH: number;
        const ENGINE_METHOD_RAND: number;
        const ENGINE_METHOD_EC: number;
        const ENGINE_METHOD_CIPHERS: number;
        const ENGINE_METHOD_DIGESTS: number;
        const ENGINE_METHOD_PKEY_METHS: number;
        const ENGINE_METHOD_PKEY_ASN1_METHS: number;
        const ENGINE_METHOD_ALL: number;
        const ENGINE_METHOD_NONE: number;
        const DH_CHECK_P_NOT_SAFE_PRIME: number;
        const DH_CHECK_P_NOT_PRIME: number;
        const DH_UNABLE_TO_CHECK_GENERATOR: number;
        const DH_NOT_SUITABLE_GENERATOR: number;
        const RSA_PKCS1_PADDING: number;
        const RSA_SSLV23_PADDING: number;
        const RSA_NO_PADDING: number;
        const RSA_PKCS1_OAEP_PADDING: number;
        const RSA_X931_PADDING: number;
        const RSA_PKCS1_PSS_PADDING: number;
        /** Sets the salt length for RSA_PKCS1_PSS_PADDING to the digest size when signing or verifying. */
        const RSA_PSS_SALTLEN_DIGEST: number;
        /** Sets the salt length for RSA_PKCS1_PSS_PADDING to the maximum permissible value when signing data. */
        const RSA_PSS_SALTLEN_MAX_SIGN: number;
        /** Causes the salt length for RSA_PKCS1_PSS_PADDING to be determined automatically when verifying a signature. */
        const RSA_PSS_SALTLEN_AUTO: number;
        const POINT_CONVERSION_COMPRESSED: number;
        const POINT_CONVERSION_UNCOMPRESSED: number;
        const POINT_CONVERSION_HYBRID: number;
        /** Specifies the built-in default cipher list used by Node.js (colon-separated values). */
        const defaultCoreCipherList: string;
        /** Specifies the active default cipher list used by the current Node.js process  (colon-separated values). */
        const defaultCipherList: string;
    }
    interface HashOptions extends stream.TransformOptions {
        /**
         * For XOF hash functions such as `shake256`, the
         * outputLength option can be used to specify the desired output length in bytes.
         */
        outputLength?: number | undefined;
    }
    /** @deprecated since v10.0.0 */
    const fips: boolean;
    /**
     * Creates and returns a `Hash` object that can be used to generate hash digests
     * using the given `algorithm`. Optional `options` argument controls stream
     * behavior. For XOF hash functions such as `'shake256'`, the `outputLength` option
     * can be used to specify the desired output length in bytes.
     *
     * The `algorithm` is dependent on the available algorithms supported by the
     * version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc.
     * On recent releases of OpenSSL, `openssl list -digest-algorithms` will
     * display the available digest algorithms.
     *
     * Example: generating the sha256 sum of a file
     *
     * ```js
     * import {
     *   createReadStream,
     * } from 'node:fs';
     * import { argv } from 'node:process';
     * const {
     *   createHash,
     * } = await import('node:crypto');
     *
     * const filename = argv[2];
     *
     * const hash = createHash('sha256');
     *
     * const input = createReadStream(filename);
     * input.on('readable', () => {
     *   // Only one element is going to be produced by the
     *   // hash stream.
     *   const data = input.read();
     *   if (data)
     *     hash.update(data);
     *   else {
     *     console.log(`${hash.digest('hex')} ${filename}`);
     *   }
     * });
     * ```
     * @since v0.1.92
     * @param options `stream.transform` options
     */
    function createHash(algorithm: string, options?: HashOptions): Hash;
    /**
     * Creates and returns an `Hmac` object that uses the given `algorithm` and `key`.
     * Optional `options` argument controls stream behavior.
     *
     * The `algorithm` is dependent on the available algorithms supported by the
     * version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc.
     * On recent releases of OpenSSL, `openssl list -digest-algorithms` will
     * display the available digest algorithms.
     *
     * The `key` is the HMAC key used to generate the cryptographic HMAC hash. If it is
     * a `KeyObject`, its type must be `secret`. If it is a string, please consider `caveats when using strings as inputs to cryptographic APIs`. If it was
     * obtained from a cryptographically secure source of entropy, such as {@link randomBytes} or {@link generateKey}, its length should not
     * exceed the block size of `algorithm` (e.g., 512 bits for SHA-256).
     *
     * Example: generating the sha256 HMAC of a file
     *
     * ```js
     * import {
     *   createReadStream,
     * } from 'node:fs';
     * import { argv } from 'node:process';
     * const {
     *   createHmac,
     * } = await import('node:crypto');
     *
     * const filename = argv[2];
     *
     * const hmac = createHmac('sha256', 'a secret');
     *
     * const input = createReadStream(filename);
     * input.on('readable', () => {
     *   // Only one element is going to be produced by the
     *   // hash stream.
     *   const data = input.read();
     *   if (data)
     *     hmac.update(data);
     *   else {
     *     console.log(`${hmac.digest('hex')} ${filename}`);
     *   }
     * });
     * ```
     * @since v0.1.94
     * @param options `stream.transform` options
     */
    function createHmac(algorithm: string, key: BinaryLike | KeyObject, options?: stream.TransformOptions): Hmac;
    // https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings
    type BinaryToTextEncoding = "base64" | "base64url" | "hex" | "binary";
    type CharacterEncoding = "utf8" | "utf-8" | "utf16le" | "utf-16le" | "latin1";
    type LegacyCharacterEncoding = "ascii" | "binary" | "ucs2" | "ucs-2";
    type Encoding = BinaryToTextEncoding | CharacterEncoding | LegacyCharacterEncoding;
    type ECDHKeyFormat = "compressed" | "uncompressed" | "hybrid";
    /**
     * The `Hash` class is a utility for creating hash digests of data. It can be
     * used in one of two ways:
     *
     * * As a `stream` that is both readable and writable, where data is written
     * to produce a computed hash digest on the readable side, or
     * * Using the `hash.update()` and `hash.digest()` methods to produce the
     * computed hash.
     *
     * The {@link createHash} method is used to create `Hash` instances. `Hash`objects are not to be created directly using the `new` keyword.
     *
     * Example: Using `Hash` objects as streams:
     *
     * ```js
     * const {
     *   createHash,
     * } = await import('node:crypto');
     *
     * const hash = createHash('sha256');
     *
     * hash.on('readable', () => {
     *   // Only one element is going to be produced by the
     *   // hash stream.
     *   const data = hash.read();
     *   if (data) {
     *     console.log(data.toString('hex'));
     *     // Prints:
     *     //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
     *   }
     * });
     *
     * hash.write('some data to hash');
     * hash.end();
     * ```
     *
     * Example: Using `Hash` and piped streams:
     *
     * ```js
     * import { createReadStream } from 'node:fs';
     * import { stdout } from 'node:process';
     * const { createHash } = await import('node:crypto');
     *
     * const hash = createHash('sha256');
     *
     * const input = createReadStream('test.js');
     * input.pipe(hash).setEncoding('hex').pipe(stdout);
     * ```
     *
     * Example: Using the `hash.update()` and `hash.digest()` methods:
     *
     * ```js
     * const {
     *   createHash,
     * } = await import('node:crypto');
     *
     * const hash = createHash('sha256');
     *
     * hash.update('some data to hash');
     * console.log(hash.digest('hex'));
     * // Prints:
     * //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
     * ```
     * @since v0.1.92
     */
    class Hash extends stream.Transform {
        private constructor();
        /**
         * Creates a new `Hash` object that contains a deep copy of the internal state
         * of the current `Hash` object.
         *
         * The optional `options` argument controls stream behavior. For XOF hash
         * functions such as `'shake256'`, the `outputLength` option can be used to
         * specify the desired output length in bytes.
         *
         * An error is thrown when an attempt is made to copy the `Hash` object after
         * its `hash.digest()` method has been called.
         *
         * ```js
         * // Calculate a rolling hash.
         * const {
         *   createHash,
         * } = await import('node:crypto');
         *
         * const hash = createHash('sha256');
         *
         * hash.update('one');
         * console.log(hash.copy().digest('hex'));
         *
         * hash.update('two');
         * console.log(hash.copy().digest('hex'));
         *
         * hash.update('three');
         * console.log(hash.copy().digest('hex'));
         *
         * // Etc.
         * ```
         * @since v13.1.0
         * @param options `stream.transform` options
         */
        copy(options?: HashOptions): Hash;
        /**
         * Updates the hash content with the given `data`, the encoding of which
         * is given in `inputEncoding`.
         * If `encoding` is not provided, and the `data` is a string, an
         * encoding of `'utf8'` is enforced. If `data` is a `Buffer`, `TypedArray`, or`DataView`, then `inputEncoding` is ignored.
         *
         * This can be called many times with new data as it is streamed.
         * @since v0.1.92
         * @param inputEncoding The `encoding` of the `data` string.
         */
        update(data: BinaryLike): Hash;
        update(data: string, inputEncoding: Encoding): Hash;
        /**
         * Calculates the digest of all of the data passed to be hashed (using the `hash.update()` method).
         * If `encoding` is provided a string will be returned; otherwise
         * a `Buffer` is returned.
         *
         * The `Hash` object can not be used again after `hash.digest()` method has been
         * called. Multiple calls will cause an error to be thrown.
         * @since v0.1.92
         * @param encoding The `encoding` of the return value.
         */
        digest(): Buffer;
        digest(encoding: BinaryToTextEncoding): string;
    }
    /**
     * The `Hmac` class is a utility for creating cryptographic HMAC digests. It can
     * be used in one of two ways:
     *
     * * As a `stream` that is both readable and writable, where data is written
     * to produce a computed HMAC digest on the readable side, or
     * * Using the `hmac.update()` and `hmac.digest()` methods to produce the
     * computed HMAC digest.
     *
     * The {@link createHmac} method is used to create `Hmac` instances. `Hmac`objects are not to be created directly using the `new` keyword.
     *
     * Example: Using `Hmac` objects as streams:
     *
     * ```js
     * const {
     *   createHmac,
     * } = await import('node:crypto');
     *
     * const hmac = createHmac('sha256', 'a secret');
     *
     * hmac.on('readable', () => {
     *   // Only one element is going to be produced by the
     *   // hash stream.
     *   const data = hmac.read();
     *   if (data) {
     *     console.log(data.toString('hex'));
     *     // Prints:
     *     //   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
     *   }
     * });
     *
     * hmac.write('some data to hash');
     * hmac.end();
     * ```
     *
     * Example: Using `Hmac` and piped streams:
     *
     * ```js
     * import { createReadStream } from 'node:fs';
     * import { stdout } from 'node:process';
     * const {
     *   createHmac,
     * } = await import('node:crypto');
     *
     * const hmac = createHmac('sha256', 'a secret');
     *
     * const input = createReadStream('test.js');
     * input.pipe(hmac).pipe(stdout);
     * ```
     *
     * Example: Using the `hmac.update()` and `hmac.digest()` methods:
     *
     * ```js
     * const {
     *   createHmac,
     * } = await import('node:crypto');
     *
     * const hmac = createHmac('sha256', 'a secret');
     *
     * hmac.update('some data to hash');
     * console.log(hmac.digest('hex'));
     * // Prints:
     * //   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
     * ```
     * @since v0.1.94
     * @deprecated Since v20.13.0 Calling `Hmac` class directly with `Hmac()` or `new Hmac()` is deprecated due to being internals, not intended for public use. Please use the {@link createHmac} method to create Hmac instances.
     */
    class Hmac extends stream.Transform {
        private constructor();
        /**
         * Updates the `Hmac` content with the given `data`, the encoding of which
         * is given in `inputEncoding`.
         * If `encoding` is not provided, and the `data` is a string, an
         * encoding of `'utf8'` is enforced. If `data` is a `Buffer`, `TypedArray`, or`DataView`, then `inputEncoding` is ignored.
         *
         * This can be called many times with new data as it is streamed.
         * @since v0.1.94
         * @param inputEncoding The `encoding` of the `data` string.
         */
        update(data: BinaryLike): Hmac;
        update(data: string, inputEncoding: Encoding): Hmac;
        /**
         * Calculates the HMAC digest of all of the data passed using `hmac.update()`.
         * If `encoding` is
         * provided a string is returned; otherwise a `Buffer` is returned;
         *
         * The `Hmac` object can not be used again after `hmac.digest()` has been
         * called. Multiple calls to `hmac.digest()` will result in an error being thrown.
         * @since v0.1.94
         * @param encoding The `encoding` of the return value.
         */
        digest(): Buffer;
        digest(encoding: BinaryToTextEncoding): string;
    }
    type KeyObjectType = "secret" | "public" | "private";
    interface KeyExportOptions<T extends KeyFormat> {
        type: "pkcs1" | "spki" | "pkcs8" | "sec1";
        format: T;
        cipher?: string | undefined;
        passphrase?: string | Buffer | undefined;
    }
    interface JwkKeyExportOptions {
        format: "jwk";
    }
    interface JsonWebKey {
        crv?: string | undefined;
        d?: string | undefined;
        dp?: string | undefined;
        dq?: string | undefined;
        e?: string | undefined;
        k?: string | undefined;
        kty?: string | undefined;
        n?: string | undefined;
        p?: string | undefined;
        q?: string | undefined;
        qi?: string | undefined;
        x?: string | undefined;
        y?: string | undefined;
        [key: string]: unknown;
    }
    interface AsymmetricKeyDetails {
        /**
         * Key size in bits (RSA, DSA).
         */
        modulusLength?: number | undefined;
        /**
         * Public exponent (RSA).
         */
        publicExponent?: bigint | undefined;
        /**
         * Name of the message digest (RSA-PSS).
         */
        hashAlgorithm?: string | undefined;
        /**
         * Name of the message digest used by MGF1 (RSA-PSS).
         */
        mgf1HashAlgorithm?: string | undefined;
        /**
         * Minimal salt length in bytes (RSA-PSS).
         */
        saltLength?: number | undefined;
        /**
         * Size of q in bits (DSA).
         */
        divisorLength?: number | undefined;
        /**
         * Name of the curve (EC).
         */
        namedCurve?: string | undefined;
    }
    /**
     * Node.js uses a `KeyObject` class to represent a symmetric or asymmetric key,
     * and each kind of key exposes different functions. The {@link createSecretKey}, {@link createPublicKey} and {@link createPrivateKey} methods are used to create `KeyObject`instances. `KeyObject`
     * objects are not to be created directly using the `new`keyword.
     *
     * Most applications should consider using the new `KeyObject` API instead of
     * passing keys as strings or `Buffer`s due to improved security features.
     *
     * `KeyObject` instances can be passed to other threads via `postMessage()`.
     * The receiver obtains a cloned `KeyObject`, and the `KeyObject` does not need to
     * be listed in the `transferList` argument.
     * @since v11.6.0
     */
    class KeyObject {
        private constructor();
        /**
         * Example: Converting a `CryptoKey` instance to a `KeyObject`:
         *
         * ```js
         * const { KeyObject } = await import('node:crypto');
         * const { subtle } = globalThis.crypto;
         *
         * const key = await subtle.generateKey({
         *   name: 'HMAC',
         *   hash: 'SHA-256',
         *   length: 256,
         * }, true, ['sign', 'verify']);
         *
         * const keyObject = KeyObject.from(key);
         * console.log(keyObject.symmetricKeySize);
         * // Prints: 32 (symmetric key size in bytes)
         * ```
         * @since v15.0.0
         */
        static from(key: webcrypto.CryptoKey): KeyObject;
        /**
         * For asymmetric keys, this property represents the type of the key. Supported key
         * types are:
         *
         * * `'rsa'` (OID 1.2.840.113549.1.1.1)
         * * `'rsa-pss'` (OID 1.2.840.113549.1.1.10)
         * * `'dsa'` (OID 1.2.840.10040.4.1)
         * * `'ec'` (OID 1.2.840.10045.2.1)
         * * `'x25519'` (OID 1.3.101.110)
         * * `'x448'` (OID 1.3.101.111)
         * * `'ed25519'` (OID 1.3.101.112)
         * * `'ed448'` (OID 1.3.101.113)
         * * `'dh'` (OID 1.2.840.113549.1.3.1)
         *
         * This property is `undefined` for unrecognized `KeyObject` types and symmetric
         * keys.
         * @since v11.6.0
         */
        asymmetricKeyType?: KeyType | undefined;
        /**
         * This property exists only on asymmetric keys. Depending on the type of the key,
         * this object contains information about the key. None of the information obtained
         * through this property can be used to uniquely identify a key or to compromise
         * the security of the key.
         *
         * For RSA-PSS keys, if the key material contains a `RSASSA-PSS-params` sequence,
         * the `hashAlgorithm`, `mgf1HashAlgorithm`, and `saltLength` properties will be
         * set.
         *
         * Other key details might be exposed via this API using additional attributes.
         * @since v15.7.0
         */
        asymmetricKeyDetails?: AsymmetricKeyDetails | undefined;
        /**
         * For symmetric keys, the following encoding options can be used:
         *
         * For public keys, the following encoding options can be used:
         *
         * For private keys, the following encoding options can be used:
         *
         * The result type depends on the selected encoding format, when PEM the
         * result is a string, when DER it will be a buffer containing the data
         * encoded as DER, when [JWK](https://tools.ietf.org/html/rfc7517) it will be an object.
         *
         * When [JWK](https://tools.ietf.org/html/rfc7517) encoding format was selected, all other encoding options are
         * ignored.
         *
         * PKCS#1, SEC1, and PKCS#8 type keys can be encrypted by using a combination of
         * the `cipher` and `format` options. The PKCS#8 `type` can be used with any`format` to encrypt any key algorithm (RSA, EC, or DH) by specifying a`cipher`. PKCS#1 and SEC1 can only be
         * encrypted by specifying a `cipher`when the PEM `format` is used. For maximum compatibility, use PKCS#8 for
         * encrypted private keys. Since PKCS#8 defines its own
         * encryption mechanism, PEM-level encryption is not supported when encrypting
         * a PKCS#8 key. See [RFC 5208](https://www.rfc-editor.org/rfc/rfc5208.txt) for PKCS#8 encryption and [RFC 1421](https://www.rfc-editor.org/rfc/rfc1421.txt) for
         * PKCS#1 and SEC1 encryption.
         * @since v11.6.0
         */
        export(options: KeyExportOptions<"pem">): string | Buffer;
        export(options?: KeyExportOptions<"der">): Buffer;
        export(options?: JwkKeyExportOptions): JsonWebKey;
        /**
         * Returns `true` or `false` depending on whether the keys have exactly the same
         * type, value, and parameters. This method is not [constant time](https://en.wikipedia.org/wiki/Timing_attack).
         * @since v17.7.0, v16.15.0
         * @param otherKeyObject A `KeyObject` with which to compare `keyObject`.
         */
        equals(otherKeyObject: KeyObject): boolean;
        /**
         * For secret keys, this property represents the size of the key in bytes. This
         * property is `undefined` for asymmetric keys.
         * @since v11.6.0
         */
        symmetricKeySize?: number | undefined;
        /**
         * Converts a `KeyObject` instance to a `CryptoKey`.
         * @since 22.10.0
         */
        toCryptoKey(
            algorithm:
                | webcrypto.AlgorithmIdentifier
                | webcrypto.RsaHashedImportParams
                | webcrypto.EcKeyImportParams
                | webcrypto.HmacImportParams,
            extractable: boolean,
            keyUsages: readonly webcrypto.KeyUsage[],
        ): webcrypto.CryptoKey;
        /**
         * Depending on the type of this `KeyObject`, this property is either`'secret'` for secret (symmetric) keys, `'public'` for public (asymmetric) keys
         * or `'private'` for private (asymmetric) keys.
         * @since v11.6.0
         */
        type: KeyObjectType;
    }
    type CipherCCMTypes = "aes-128-ccm" | "aes-192-ccm" | "aes-256-ccm" | "chacha20-poly1305";
    type CipherGCMTypes = "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm";
    type CipherOCBTypes = "aes-128-ocb" | "aes-192-ocb" | "aes-256-ocb";
    type BinaryLike = string | NodeJS.ArrayBufferView;
    type CipherKey = BinaryLike | KeyObject;
    interface CipherCCMOptions extends stream.TransformOptions {
        authTagLength: number;
    }
    interface CipherGCMOptions extends stream.TransformOptions {
        authTagLength?: number | undefined;
    }
    interface CipherOCBOptions extends stream.TransformOptions {
        authTagLength: number;
    }
    /**
     * Creates and returns a `Cipher` object, with the given `algorithm`, `key` and
     * initialization vector (`iv`).
     *
     * The `options` argument controls stream behavior and is optional except when a
     * cipher in CCM or OCB mode (e.g. `'aes-128-ccm'`) is used. In that case, the`authTagLength` option is required and specifies the length of the
     * authentication tag in bytes, see `CCM mode`. In GCM mode, the `authTagLength`option is not required but can be used to set the length of the authentication
     * tag that will be returned by `getAuthTag()` and defaults to 16 bytes.
     * For `chacha20-poly1305`, the `authTagLength` option defaults to 16 bytes.
     *
     * The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On
     * recent OpenSSL releases, `openssl list -cipher-algorithms` will
     * display the available cipher algorithms.
     *
     * The `key` is the raw key used by the `algorithm` and `iv` is an [initialization vector](https://en.wikipedia.org/wiki/Initialization_vector). Both arguments must be `'utf8'` encoded
     * strings,`Buffers`, `TypedArray`, or `DataView`s. The `key` may optionally be
     * a `KeyObject` of type `secret`. If the cipher does not need
     * an initialization vector, `iv` may be `null`.
     *
     * When passing strings for `key` or `iv`, please consider `caveats when using strings as inputs to cryptographic APIs`.
     *
     * Initialization vectors should be unpredictable and unique; ideally, they will be
     * cryptographically random. They do not have to be secret: IVs are typically just
     * added to ciphertext messages unencrypted. It may sound contradictory that
     * something has to be unpredictable and unique, but does not have to be secret;
     * remember that an attacker must not be able to predict ahead of time what a
     * given IV will be.
     * @since v0.1.94
     * @param options `stream.transform` options
     */
    function createCipheriv(
        algorithm: CipherCCMTypes,
        key: CipherKey,
        iv: BinaryLike,
        options: CipherCCMOptions,
    ): CipherCCM;
    function createCipheriv(
        algorithm: CipherOCBTypes,
        key: CipherKey,
        iv: BinaryLike,
        options: CipherOCBOptions,
    ): CipherOCB;
    function createCipheriv(
        algorithm: CipherGCMTypes,
        key: CipherKey,
        iv: BinaryLike,
        options?: CipherGCMOptions,
    ): CipherGCM;
    function createCipheriv(
        algorithm: string,
        key: CipherKey,
        iv: BinaryLike | null,
        options?: stream.TransformOptions,
    ): Cipher;
    /**
     * Instances of the `Cipher` class are used to encrypt data. The class can be
     * used in one of two ways:
     *
     * * As a `stream` that is both readable and writable, where plain unencrypted
     * data is written to produce encrypted data on the readable side, or
     * * Using the `cipher.update()` and `cipher.final()` methods to produce
     * the encrypted data.
     *
     * The {@link createCipheriv} method is
     * used to create `Cipher` instances. `Cipher` objects are not to be created
     * directly using the `new` keyword.
     *
     * Example: Using `Cipher` objects as streams:
     *
     * ```js
     * const {
     *   scrypt,
     *   randomFill,
     *   createCipheriv,
     * } = await import('node:crypto');
     *
     * const algorithm = 'aes-192-cbc';
     * const password = 'Password used to generate key';
     *
     * // First, we'll generate the key. The key length is dependent on the algorithm.
     * // In this case for aes192, it is 24 bytes (192 bits).
     * scrypt(password, 'salt', 24, (err, key) => {
     *   if (err) throw err;
     *   // Then, we'll generate a random initialization vector
     *   randomFill(new Uint8Array(16), (err, iv) => {
     *     if (err) throw err;
     *
     *     // Once we have the key and iv, we can create and use the cipher...
     *     const cipher = createCipheriv(algorithm, key, iv);
     *
     *     let encrypted = '';
     *     cipher.setEncoding('hex');
     *
     *     cipher.on('data', (chunk) => encrypted += chunk);
     *     cipher.on('end', () => console.log(encrypted));
     *
     *     cipher.write('some clear text data');
     *     cipher.end();
     *   });
     * });
     * ```
     *
     * Example: Using `Cipher` and piped streams:
     *
     * ```js
     * import {
     *   createReadStream,
     *   createWriteStream,
     * } from 'node:fs';
     *
     * import {
     *   pipeline,
     * } from 'node:stream';
     *
     * const {
     *   scrypt,
     *   randomFill,
     *   createCipheriv,
     * } = await import('node:crypto');
     *
     * const algorithm = 'aes-192-cbc';
     * const password = 'Password used to generate key';
     *
     * // First, we'll generate the key. The key length is dependent on the algorithm.
     * // In this case for aes192, it is 24 bytes (192 bits).
     * scrypt(password, 'salt', 24, (err, key) => {
     *   if (err) throw err;
     *   // Then, we'll generate a random initialization vector
     *   randomFill(new Uint8Array(16), (err, iv) => {
     *     if (err) throw err;
     *
     *     const cipher = createCipheriv(algorithm, key, iv);
     *
     *     const input = createReadStream('test.js');
     *     const output = createWriteStream('test.enc');
     *
     *     pipeline(input, cipher, output, (err) => {
     *       if (err) throw err;
     *     });
     *   });
     * });
     * ```
     *
     * Example: Using the `cipher.update()` and `cipher.final()` methods:
     *
     * ```js
     * const {
     *   scrypt,
     *   randomFill,
     *   createCipheriv,
     * } = await import('node:crypto');
     *
     * const algorithm = 'aes-192-cbc';
     * const password = 'Password used to generate key';
     *
     * // First, we'll generate the key. The key length is dependent on the algorithm.
     * // In this case for aes192, it is 24 bytes (192 bits).
     * scrypt(password, 'salt', 24, (err, key) => {
     *   if (err) throw err;
     *   // Then, we'll generate a random initialization vector
     *   randomFill(new Uint8Array(16), (err, iv) => {
     *     if (err) throw err;
     *
     *     const cipher = createCipheriv(algorithm, key, iv);
     *
     *     let encrypted = cipher.update('some clear text data', 'utf8', 'hex');
     *     encrypted += cipher.final('hex');
     *     console.log(encrypted);
     *   });
     * });
     * ```
     * @since v0.1.94
     */
    class Cipher extends stream.Transform {
        private constructor();
        /**
         * Updates the cipher with `data`. If the `inputEncoding` argument is given,
         * the `data`argument is a string using the specified encoding. If the `inputEncoding`argument is not given, `data` must be a `Buffer`, `TypedArray`, or `DataView`. If `data` is a `Buffer`,
         * `TypedArray`, or `DataView`, then `inputEncoding` is ignored.
         *
         * The `outputEncoding` specifies the output format of the enciphered
         * data. If the `outputEncoding`is specified, a string using the specified encoding is returned. If no`outputEncoding` is provided, a `Buffer` is returned.
         *
         * The `cipher.update()` method can be called multiple times with new data until `cipher.final()` is called. Calling `cipher.update()` after `cipher.final()` will result in an error being
         * thrown.
         * @since v0.1.94
         * @param inputEncoding The `encoding` of the data.
         * @param outputEncoding The `encoding` of the return value.
         */
        update(data: BinaryLike): Buffer;
        update(data: string, inputEncoding: Encoding): Buffer;
        update(data: NodeJS.ArrayBufferView, inputEncoding: undefined, outputEncoding: Encoding): string;
        update(data: string, inputEncoding: Encoding | undefined, outputEncoding: Encoding): string;
        /**
         * Once the `cipher.final()` method has been called, the `Cipher` object can no
         * longer be used to encrypt data. Attempts to call `cipher.final()` more than
         * once will result in an error being thrown.
         * @since v0.1.94
         * @param outputEncoding The `encoding` of the return value.
         * @return Any remaining enciphered contents. If `outputEncoding` is specified, a string is returned. If an `outputEncoding` is not provided, a {@link Buffer} is returned.
         */
        final(): Buffer;
        final(outputEncoding: BufferEncoding): string;
        /**
         * When using block encryption algorithms, the `Cipher` class will automatically
         * add padding to the input data to the appropriate block size. To disable the
         * default padding call `cipher.setAutoPadding(false)`.
         *
         * When `autoPadding` is `false`, the length of the entire input data must be a
         * multiple of the cipher's block size or `cipher.final()` will throw an error.
         * Disabling automatic padding is useful for non-standard padding, for instance
         * using `0x0` instead of PKCS padding.
         *
         * The `cipher.setAutoPadding()` method must be called before `cipher.final()`.
         * @since v0.7.1
         * @param [autoPadding=true]
         * @return for method chaining.
         */
        setAutoPadding(autoPadding?: boolean): this;
    }
    interface CipherCCM extends Cipher {
        setAAD(
            buffer: NodeJS.ArrayBufferView,
            options: {
                plaintextLength: number;
            },
        ): this;
        getAuthTag(): Buffer;
    }
    interface CipherGCM extends Cipher {
        setAAD(
            buffer: NodeJS.ArrayBufferView,
            options?: {
                plaintextLength: number;
            },
        ): this;
        getAuthTag(): Buffer;
    }
    interface CipherOCB extends Cipher {
        setAAD(
            buffer: NodeJS.ArrayBufferView,
            options?: {
                plaintextLength: number;
            },
        ): this;
        getAuthTag(): Buffer;
    }
    /**
     * Creates and returns a `Decipher` object that uses the given `algorithm`, `key` and initialization vector (`iv`).
     *
     * The `options` argument controls stream behavior and is optional except when a
     * cipher in CCM or OCB mode (e.g. `'aes-128-ccm'`) is used. In that case, the `authTagLength` option is required and specifies the length of the
     * authentication tag in bytes, see `CCM mode`. In GCM mode, the `authTagLength` option is not required but can be used to restrict accepted authentication tags
     * to those with the specified length.
     * For `chacha20-poly1305`, the `authTagLength` option defaults to 16 bytes.
     *
     * The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On
     * recent OpenSSL releases, `openssl list -cipher-algorithms` will
     * display the available cipher algorithms.
     *
     * The `key` is the raw key used by the `algorithm` and `iv` is an [initialization vector](https://en.wikipedia.org/wiki/Initialization_vector). Both arguments must be `'utf8'` encoded
     * strings,`Buffers`, `TypedArray`, or `DataView`s. The `key` may optionally be
     * a `KeyObject` of type `secret`. If the cipher does not need
     * an initialization vector, `iv` may be `null`.
     *
     * When passing strings for `key` or `iv`, please consider `caveats when using strings as inputs to cryptographic APIs`.
     *
     * Initialization vectors should be unpredictable and unique; ideally, they will be
     * cryptographically random. They do not have to be secret: IVs are typically just
     * added to ciphertext messages unencrypted. It may sound contradictory that
     * something has to be unpredictable and unique, but does not have to be secret;
     * remember that an attacker must not be able to predict ahead of time what a given
     * IV will be.
     * @since v0.1.94
     * @param options `stream.transform` options
     */
    function createDecipheriv(
        algorithm: CipherCCMTypes,
        key: CipherKey,
        iv: BinaryLike,
        options: CipherCCMOptions,
    ): DecipherCCM;
    function createDecipheriv(
        algorithm: CipherOCBTypes,
        key: CipherKey,
        iv: BinaryLike,
        options: CipherOCBOptions,
    ): DecipherOCB;
    function createDecipheriv(
        algorithm: CipherGCMTypes,
        key: CipherKey,
        iv: BinaryLike,
        options?: CipherGCMOptions,
    ): DecipherGCM;
    function createDecipheriv(
        algorithm: string,
        key: CipherKey,
        iv: BinaryLike | null,
        options?: stream.TransformOptions,
    ): Decipher;
    /**
     * Instances of the `Decipher` class are used to decrypt data. The class can be
     * used in one of two ways:
     *
     * * As a `stream` that is both readable and writable, where plain encrypted
     * data is written to produce unencrypted data on the readable side, or
     * * Using the `decipher.update()` and `decipher.final()` methods to
     * produce the unencrypted data.
     *
     * The {@link createDecipheriv} method is
     * used to create `Decipher` instances. `Decipher` objects are not to be created
     * directly using the `new` keyword.
     *
     * Example: Using `Decipher` objects as streams:
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const {
     *   scryptSync,
     *   createDecipheriv,
     * } = await import('node:crypto');
     *
     * const algorithm = 'aes-192-cbc';
     * const password = 'Password used to generate key';
     * // Key length is dependent on the algorithm. In this case for aes192, it is
     * // 24 bytes (192 bits).
     * // Use the async `crypto.scrypt()` instead.
     * const key = scryptSync(password, 'salt', 24);
     * // The IV is usually passed along with the ciphertext.
     * const iv = Buffer.alloc(16, 0); // Initialization vector.
     *
     * const decipher = createDecipheriv(algorithm, key, iv);
     *
     * let decrypted = '';
     * decipher.on('readable', () => {
     *   let chunk;
     *   while (null !== (chunk = decipher.read())) {
     *     decrypted += chunk.toString('utf8');
     *   }
     * });
     * decipher.on('end', () => {
     *   console.log(decrypted);
     *   // Prints: some clear text data
     * });
     *
     * // Encrypted with same algorithm, key and iv.
     * const encrypted =
     *   'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
     * decipher.write(encrypted, 'hex');
     * decipher.end();
     * ```
     *
     * Example: Using `Decipher` and piped streams:
     *
     * ```js
     * import {
     *   createReadStream,
     *   createWriteStream,
     * } from 'node:fs';
     * import { Buffer } from 'node:buffer';
     * const {
     *   scryptSync,
     *   createDecipheriv,
     * } = await import('node:crypto');
     *
     * const algorithm = 'aes-192-cbc';
     * const password = 'Password used to generate key';
     * // Use the async `crypto.scrypt()` instead.
     * const key = scryptSync(password, 'salt', 24);
     * // The IV is usually passed along with the ciphertext.
     * const iv = Buffer.alloc(16, 0); // Initialization vector.
     *
     * const decipher = createDecipheriv(algorithm, key, iv);
     *
     * const input = createReadStream('test.enc');
     * const output = createWriteStream('test.js');
     *
     * input.pipe(decipher).pipe(output);
     * ```
     *
     * Example: Using the `decipher.update()` and `decipher.final()` methods:
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const {
     *   scryptSync,
     *   createDecipheriv,
     * } = await import('node:crypto');
     *
     * const algorithm = 'aes-192-cbc';
     * const password = 'Password used to generate key';
     * // Use the async `crypto.scrypt()` instead.
     * const key = scryptSync(password, 'salt', 24);
     * // The IV is usually passed along with the ciphertext.
     * const iv = Buffer.alloc(16, 0); // Initialization vector.
     *
     * const decipher = createDecipheriv(algorithm, key, iv);
     *
     * // Encrypted using same algorithm, key and iv.
     * const encrypted =
     *   'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
     * let decrypted = decipher.update(encrypted, 'hex', 'utf8');
     * decrypted += decipher.final('utf8');
     * console.log(decrypted);
     * // Prints: some clear text data
     * ```
     * @since v0.1.94
     */
    class Decipher extends stream.Transform {
        private constructor();
        /**
         * Updates the decipher with `data`. If the `inputEncoding` argument is given,
         * the `data` argument is a string using the specified encoding. If the `inputEncoding` argument is not given, `data` must be a `Buffer`. If `data` is a `Buffer` then `inputEncoding` is
         * ignored.
         *
         * The `outputEncoding` specifies the output format of the enciphered
         * data. If the `outputEncoding` is specified, a string using the specified encoding is returned. If no `outputEncoding` is provided, a `Buffer` is returned.
         *
         * The `decipher.update()` method can be called multiple times with new data until `decipher.final()` is called. Calling `decipher.update()` after `decipher.final()` will result in an error
         * being thrown.
         * @since v0.1.94
         * @param inputEncoding The `encoding` of the `data` string.
         * @param outputEncoding The `encoding` of the return value.
         */
        update(data: NodeJS.ArrayBufferView): Buffer;
        update(data: string, inputEncoding: Encoding): Buffer;
        update(data: NodeJS.ArrayBufferView, inputEncoding: undefined, outputEncoding: Encoding): string;
        update(data: string, inputEncoding: Encoding | undefined, outputEncoding: Encoding): string;
        /**
         * Once the `decipher.final()` method has been called, the `Decipher` object can
         * no longer be used to decrypt data. Attempts to call `decipher.final()` more
         * than once will result in an error being thrown.
         * @since v0.1.94
         * @param outputEncoding The `encoding` of the return value.
         * @return Any remaining deciphered contents. If `outputEncoding` is specified, a string is returned. If an `outputEncoding` is not provided, a {@link Buffer} is returned.
         */
        final(): Buffer;
        final(outputEncoding: BufferEncoding): string;
        /**
         * When data has been encrypted without standard block padding, calling `decipher.setAutoPadding(false)` will disable automatic padding to prevent `decipher.final()` from checking for and
         * removing padding.
         *
         * Turning auto padding off will only work if the input data's length is a
         * multiple of the ciphers block size.
         *
         * The `decipher.setAutoPadding()` method must be called before `decipher.final()`.
         * @since v0.7.1
         * @param [autoPadding=true]
         * @return for method chaining.
         */
        setAutoPadding(auto_padding?: boolean): this;
    }
    interface DecipherCCM extends Decipher {
        setAuthTag(buffer: NodeJS.ArrayBufferView): this;
        setAAD(
            buffer: NodeJS.ArrayBufferView,
            options: {
                plaintextLength: number;
            },
        ): this;
    }
    interface DecipherGCM extends Decipher {
        setAuthTag(buffer: NodeJS.ArrayBufferView): this;
        setAAD(
            buffer: NodeJS.ArrayBufferView,
            options?: {
                plaintextLength: number;
            },
        ): this;
    }
    interface DecipherOCB extends Decipher {
        setAuthTag(buffer: NodeJS.ArrayBufferView): this;
        setAAD(
            buffer: NodeJS.ArrayBufferView,
            options?: {
                plaintextLength: number;
            },
        ): this;
    }
    interface PrivateKeyInput {
        key: string | Buffer;
        format?: KeyFormat | undefined;
        type?: "pkcs1" | "pkcs8" | "sec1" | undefined;
        passphrase?: string | Buffer | undefined;
        encoding?: string | undefined;
    }
    interface PublicKeyInput {
        key: string | Buffer;
        format?: KeyFormat | undefined;
        type?: "pkcs1" | "spki" | undefined;
        encoding?: string | undefined;
    }
    /**
     * Asynchronously generates a new random secret key of the given `length`. The `type` will determine which validations will be performed on the `length`.
     *
     * ```js
     * const {
     *   generateKey,
     * } = await import('node:crypto');
     *
     * generateKey('hmac', { length: 512 }, (err, key) => {
     *   if (err) throw err;
     *   console.log(key.export().toString('hex'));  // 46e..........620
     * });
     * ```
     *
     * The size of a generated HMAC key should not exceed the block size of the
     * underlying hash function. See {@link createHmac} for more information.
     * @since v15.0.0
     * @param type The intended use of the generated secret key. Currently accepted values are `'hmac'` and `'aes'`.
     */
    function generateKey(
        type: "hmac" | "aes",
        options: {
            length: number;
        },
        callback: (err: Error | null, key: KeyObject) => void,
    ): void;
    /**
     * Synchronously generates a new random secret key of the given `length`. The `type` will determine which validations will be performed on the `length`.
     *
     * ```js
     * const {
     *   generateKeySync,
     * } = await import('node:crypto');
     *
     * const key = generateKeySync('hmac', { length: 512 });
     * console.log(key.export().toString('hex'));  // e89..........41e
     * ```
     *
     * The size of a generated HMAC key should not exceed the block size of the
     * underlying hash function. See {@link createHmac} for more information.
     * @since v15.0.0
     * @param type The intended use of the generated secret key. Currently accepted values are `'hmac'` and `'aes'`.
     */
    function generateKeySync(
        type: "hmac" | "aes",
        options: {
            length: number;
        },
    ): KeyObject;
    interface JsonWebKeyInput {
        key: JsonWebKey;
        format: "jwk";
    }
    /**
     * Creates and returns a new key object containing a private key. If `key` is a
     * string or `Buffer`, `format` is assumed to be `'pem'`; otherwise, `key` must be an object with the properties described above.
     *
     * If the private key is encrypted, a `passphrase` must be specified. The length
     * of the passphrase is limited to 1024 bytes.
     * @since v11.6.0
     */
    function createPrivateKey(key: PrivateKeyInput | string | Buffer | JsonWebKeyInput): KeyObject;
    /**
     * Creates and returns a new key object containing a public key. If `key` is a
     * string or `Buffer`, `format` is assumed to be `'pem'`; if `key` is a `KeyObject` with type `'private'`, the public key is derived from the given private key;
     * otherwise, `key` must be an object with the properties described above.
     *
     * If the format is `'pem'`, the `'key'` may also be an X.509 certificate.
     *
     * Because public keys can be derived from private keys, a private key may be
     * passed instead of a public key. In that case, this function behaves as if {@link createPrivateKey} had been called, except that the type of the
     * returned `KeyObject` will be `'public'` and that the private key cannot be
     * extracted from the returned `KeyObject`. Similarly, if a `KeyObject` with type `'private'` is given, a new `KeyObject` with type `'public'` will be returned
     * and it will be impossible to extract the private key from the returned object.
     * @since v11.6.0
     */
    function createPublicKey(key: PublicKeyInput | string | Buffer | KeyObject | JsonWebKeyInput): KeyObject;
    /**
     * Creates and returns a new key object containing a secret key for symmetric
     * encryption or `Hmac`.
     * @since v11.6.0
     * @param encoding The string encoding when `key` is a string.
     */
    function createSecretKey(key: NodeJS.ArrayBufferView): KeyObject;
    function createSecretKey(key: string, encoding: BufferEncoding): KeyObject;
    /**
     * Creates and returns a `Sign` object that uses the given `algorithm`. Use {@link getHashes} to obtain the names of the available digest algorithms.
     * Optional `options` argument controls the `stream.Writable` behavior.
     *
     * In some cases, a `Sign` instance can be created using the name of a signature
     * algorithm, such as `'RSA-SHA256'`, instead of a digest algorithm. This will use
     * the corresponding digest algorithm. This does not work for all signature
     * algorithms, such as `'ecdsa-with-SHA256'`, so it is best to always use digest
     * algorithm names.
     * @since v0.1.92
     * @param options `stream.Writable` options
     */
    function createSign(algorithm: string, options?: stream.WritableOptions): Sign;
    type DSAEncoding = "der" | "ieee-p1363";
    interface SigningOptions {
        /**
         * @see crypto.constants.RSA_PKCS1_PADDING
         */
        padding?: number | undefined;
        saltLength?: number | undefined;
        dsaEncoding?: DSAEncoding | undefined;
    }
    interface SignPrivateKeyInput extends PrivateKeyInput, SigningOptions {}
    interface SignKeyObjectInput extends SigningOptions {
        key: KeyObject;
    }
    interface SignJsonWebKeyInput extends JsonWebKeyInput, SigningOptions {}
    interface VerifyPublicKeyInput extends PublicKeyInput, SigningOptions {}
    interface VerifyKeyObjectInput extends SigningOptions {
        key: KeyObject;
    }
    interface VerifyJsonWebKeyInput extends JsonWebKeyInput, SigningOptions {}
    type KeyLike = string | Buffer | KeyObject;
    /**
     * The `Sign` class is a utility for generating signatures. It can be used in one
     * of two ways:
     *
     * * As a writable `stream`, where data to be signed is written and the `sign.sign()` method is used to generate and return the signature, or
     * * Using the `sign.update()` and `sign.sign()` methods to produce the
     * signature.
     *
     * The {@link createSign} method is used to create `Sign` instances. The
     * argument is the string name of the hash function to use. `Sign` objects are not
     * to be created directly using the `new` keyword.
     *
     * Example: Using `Sign` and `Verify` objects as streams:
     *
     * ```js
     * const {
     *   generateKeyPairSync,
     *   createSign,
     *   createVerify,
     * } = await import('node:crypto');
     *
     * const { privateKey, publicKey } = generateKeyPairSync('ec', {
     *   namedCurve: 'sect239k1',
     * });
     *
     * const sign = createSign('SHA256');
     * sign.write('some data to sign');
     * sign.end();
     * const signature = sign.sign(privateKey, 'hex');
     *
     * const verify = createVerify('SHA256');
     * verify.write('some data to sign');
     * verify.end();
     * console.log(verify.verify(publicKey, signature, 'hex'));
     * // Prints: true
     * ```
     *
     * Example: Using the `sign.update()` and `verify.update()` methods:
     *
     * ```js
     * const {
     *   generateKeyPairSync,
     *   createSign,
     *   createVerify,
     * } = await import('node:crypto');
     *
     * const { privateKey, publicKey } = generateKeyPairSync('rsa', {
     *   modulusLength: 2048,
     * });
     *
     * const sign = createSign('SHA256');
     * sign.update('some data to sign');
     * sign.end();
     * const signature = sign.sign(privateKey);
     *
     * const verify = createVerify('SHA256');
     * verify.update('some data to sign');
     * verify.end();
     * console.log(verify.verify(publicKey, signature));
     * // Prints: true
     * ```
     * @since v0.1.92
     */
    class Sign extends stream.Writable {
        private constructor();
        /**
         * Updates the `Sign` content with the given `data`, the encoding of which
         * is given in `inputEncoding`.
         * If `encoding` is not provided, and the `data` is a string, an
         * encoding of `'utf8'` is enforced. If `data` is a `Buffer`, `TypedArray`, or`DataView`, then `inputEncoding` is ignored.
         *
         * This can be called many times with new data as it is streamed.
         * @since v0.1.92
         * @param inputEncoding The `encoding` of the `data` string.
         */
        update(data: BinaryLike): this;
        update(data: string, inputEncoding: Encoding): this;
        /**
         * Calculates the signature on all the data passed through using either `sign.update()` or `sign.write()`.
         *
         * If `privateKey` is not a `KeyObject`, this function behaves as if `privateKey` had been passed to {@link createPrivateKey}. If it is an
         * object, the following additional properties can be passed:
         *
         * If `outputEncoding` is provided a string is returned; otherwise a `Buffer` is returned.
         *
         * The `Sign` object can not be again used after `sign.sign()` method has been
         * called. Multiple calls to `sign.sign()` will result in an error being thrown.
         * @since v0.1.92
         */
        sign(privateKey: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput): Buffer;
        sign(
            privateKey: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput,
            outputFormat: BinaryToTextEncoding,
        ): string;
    }
    /**
     * Creates and returns a `Verify` object that uses the given algorithm.
     * Use {@link getHashes} to obtain an array of names of the available
     * signing algorithms. Optional `options` argument controls the `stream.Writable` behavior.
     *
     * In some cases, a `Verify` instance can be created using the name of a signature
     * algorithm, such as `'RSA-SHA256'`, instead of a digest algorithm. This will use
     * the corresponding digest algorithm. This does not work for all signature
     * algorithms, such as `'ecdsa-with-SHA256'`, so it is best to always use digest
     * algorithm names.
     * @since v0.1.92
     * @param options `stream.Writable` options
     */
    function createVerify(algorithm: string, options?: stream.WritableOptions): Verify;
    /**
     * The `Verify` class is a utility for verifying signatures. It can be used in one
     * of two ways:
     *
     * * As a writable `stream` where written data is used to validate against the
     * supplied signature, or
     * * Using the `verify.update()` and `verify.verify()` methods to verify
     * the signature.
     *
     * The {@link createVerify} method is used to create `Verify` instances. `Verify` objects are not to be created directly using the `new` keyword.
     *
     * See `Sign` for examples.
     * @since v0.1.92
     */
    class Verify extends stream.Writable {
        private constructor();
        /**
         * Updates the `Verify` content with the given `data`, the encoding of which
         * is given in `inputEncoding`.
         * If `inputEncoding` is not provided, and the `data` is a string, an
         * encoding of `'utf8'` is enforced. If `data` is a `Buffer`, `TypedArray`, or `DataView`, then `inputEncoding` is ignored.
         *
         * This can be called many times with new data as it is streamed.
         * @since v0.1.92
         * @param inputEncoding The `encoding` of the `data` string.
         */
        update(data: BinaryLike): Verify;
        update(data: string, inputEncoding: Encoding): Verify;
        /**
         * Verifies the provided data using the given `object` and `signature`.
         *
         * If `object` is not a `KeyObject`, this function behaves as if `object` had been passed to {@link createPublicKey}. If it is an
         * object, the following additional properties can be passed:
         *
         * The `signature` argument is the previously calculated signature for the data, in
         * the `signatureEncoding`.
         * If a `signatureEncoding` is specified, the `signature` is expected to be a
         * string; otherwise `signature` is expected to be a `Buffer`, `TypedArray`, or `DataView`.
         *
         * The `verify` object can not be used again after `verify.verify()` has been
         * called. Multiple calls to `verify.verify()` will result in an error being
         * thrown.
         *
         * Because public keys can be derived from private keys, a private key may
         * be passed instead of a public key.
         * @since v0.1.92
         */
        verify(
            object: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
            signature: NodeJS.ArrayBufferView,
        ): boolean;
        verify(
            object: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
            signature: string,
            signature_format?: BinaryToTextEncoding,
        ): boolean;
    }
    /**
     * Creates a `DiffieHellman` key exchange object using the supplied `prime` and an
     * optional specific `generator`.
     *
     * The `generator` argument can be a number, string, or `Buffer`. If `generator` is not specified, the value `2` is used.
     *
     * If `primeEncoding` is specified, `prime` is expected to be a string; otherwise
     * a `Buffer`, `TypedArray`, or `DataView` is expected.
     *
     * If `generatorEncoding` is specified, `generator` is expected to be a string;
     * otherwise a number, `Buffer`, `TypedArray`, or `DataView` is expected.
     * @since v0.11.12
     * @param primeEncoding The `encoding` of the `prime` string.
     * @param [generator=2]
     * @param generatorEncoding The `encoding` of the `generator` string.
     */
    function createDiffieHellman(primeLength: number, generator?: number): DiffieHellman;
    function createDiffieHellman(
        prime: ArrayBuffer | NodeJS.ArrayBufferView,
        generator?: number | ArrayBuffer | NodeJS.ArrayBufferView,
    ): DiffieHellman;
    function createDiffieHellman(
        prime: ArrayBuffer | NodeJS.ArrayBufferView,
        generator: string,
        generatorEncoding: BinaryToTextEncoding,
    ): DiffieHellman;
    function createDiffieHellman(
        prime: string,
        primeEncoding: BinaryToTextEncoding,
        generator?: number | ArrayBuffer | NodeJS.ArrayBufferView,
    ): DiffieHellman;
    function createDiffieHellman(
        prime: string,
        primeEncoding: BinaryToTextEncoding,
        generator: string,
        generatorEncoding: BinaryToTextEncoding,
    ): DiffieHellman;
    /**
     * The `DiffieHellman` class is a utility for creating Diffie-Hellman key
     * exchanges.
     *
     * Instances of the `DiffieHellman` class can be created using the {@link createDiffieHellman} function.
     *
     * ```js
     * import assert from 'node:assert';
     *
     * const {
     *   createDiffieHellman,
     * } = await import('node:crypto');
     *
     * // Generate Alice's keys...
     * const alice = createDiffieHellman(2048);
     * const aliceKey = alice.generateKeys();
     *
     * // Generate Bob's keys...
     * const bob = createDiffieHellman(alice.getPrime(), alice.getGenerator());
     * const bobKey = bob.generateKeys();
     *
     * // Exchange and generate the secret...
     * const aliceSecret = alice.computeSecret(bobKey);
     * const bobSecret = bob.computeSecret(aliceKey);
     *
     * // OK
     * assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
     * ```
     * @since v0.5.0
     */
    class DiffieHellman {
        private constructor();
        /**
         * Generates private and public Diffie-Hellman key values unless they have been
         * generated or computed already, and returns
         * the public key in the specified `encoding`. This key should be
         * transferred to the other party.
         * If `encoding` is provided a string is returned; otherwise a `Buffer` is returned.
         *
         * This function is a thin wrapper around [`DH_generate_key()`](https://www.openssl.org/docs/man3.0/man3/DH_generate_key.html). In particular,
         * once a private key has been generated or set, calling this function only updates
         * the public key but does not generate a new private key.
         * @since v0.5.0
         * @param encoding The `encoding` of the return value.
         */
        generateKeys(): Buffer;
        generateKeys(encoding: BinaryToTextEncoding): string;
        /**
         * Computes the shared secret using `otherPublicKey` as the other
         * party's public key and returns the computed shared secret. The supplied
         * key is interpreted using the specified `inputEncoding`, and secret is
         * encoded using specified `outputEncoding`.
         * If the `inputEncoding` is not
         * provided, `otherPublicKey` is expected to be a `Buffer`, `TypedArray`, or `DataView`.
         *
         * If `outputEncoding` is given a string is returned; otherwise, a `Buffer` is returned.
         * @since v0.5.0
         * @param inputEncoding The `encoding` of an `otherPublicKey` string.
         * @param outputEncoding The `encoding` of the return value.
         */
        computeSecret(otherPublicKey: NodeJS.ArrayBufferView, inputEncoding?: null, outputEncoding?: null): Buffer;
        computeSecret(otherPublicKey: string, inputEncoding: BinaryToTextEncoding, outputEncoding?: null): Buffer;
        computeSecret(
            otherPublicKey: NodeJS.ArrayBufferView,
            inputEncoding: null,
            outputEncoding: BinaryToTextEncoding,
        ): string;
        computeSecret(
            otherPublicKey: string,
            inputEncoding: BinaryToTextEncoding,
            outputEncoding: BinaryToTextEncoding,
        ): string;
        /**
         * Returns the Diffie-Hellman prime in the specified `encoding`.
         * If `encoding` is provided a string is
         * returned; otherwise a `Buffer` is returned.
         * @since v0.5.0
         * @param encoding The `encoding` of the return value.
         */
        getPrime(): Buffer;
        getPrime(encoding: BinaryToTextEncoding): string;
        /**
         * Returns the Diffie-Hellman generator in the specified `encoding`.
         * If `encoding` is provided a string is
         * returned; otherwise a `Buffer` is returned.
         * @since v0.5.0
         * @param encoding The `encoding` of the return value.
         */
        getGenerator(): Buffer;
        getGenerator(encoding: BinaryToTextEncoding): string;
        /**
         * Returns the Diffie-Hellman public key in the specified `encoding`.
         * If `encoding` is provided a
         * string is returned; otherwise a `Buffer` is returned.
         * @since v0.5.0
         * @param encoding The `encoding` of the return value.
         */
        getPublicKey(): Buffer;
        getPublicKey(encoding: BinaryToTextEncoding): string;
        /**
         * Returns the Diffie-Hellman private key in the specified `encoding`.
         * If `encoding` is provided a
         * string is returned; otherwise a `Buffer` is returned.
         * @since v0.5.0
         * @param encoding The `encoding` of the return value.
         */
        getPrivateKey(): Buffer;
        getPrivateKey(encoding: BinaryToTextEncoding): string;
        /**
         * Sets the Diffie-Hellman public key. If the `encoding` argument is provided, `publicKey` is expected
         * to be a string. If no `encoding` is provided, `publicKey` is expected
         * to be a `Buffer`, `TypedArray`, or `DataView`.
         * @since v0.5.0
         * @param encoding The `encoding` of the `publicKey` string.
         */
        setPublicKey(publicKey: NodeJS.ArrayBufferView): void;
        setPublicKey(publicKey: string, encoding: BufferEncoding): void;
        /**
         * Sets the Diffie-Hellman private key. If the `encoding` argument is provided,`privateKey` is expected
         * to be a string. If no `encoding` is provided, `privateKey` is expected
         * to be a `Buffer`, `TypedArray`, or `DataView`.
         *
         * This function does not automatically compute the associated public key. Either `diffieHellman.setPublicKey()` or `diffieHellman.generateKeys()` can be
         * used to manually provide the public key or to automatically derive it.
         * @since v0.5.0
         * @param encoding The `encoding` of the `privateKey` string.
         */
        setPrivateKey(privateKey: NodeJS.ArrayBufferView): void;
        setPrivateKey(privateKey: string, encoding: BufferEncoding): void;
        /**
         * A bit field containing any warnings and/or errors resulting from a check
         * performed during initialization of the `DiffieHellman` object.
         *
         * The following values are valid for this property (as defined in `node:constants` module):
         *
         * * `DH_CHECK_P_NOT_SAFE_PRIME`
         * * `DH_CHECK_P_NOT_PRIME`
         * * `DH_UNABLE_TO_CHECK_GENERATOR`
         * * `DH_NOT_SUITABLE_GENERATOR`
         * @since v0.11.12
         */
        verifyError: number;
    }
    /**
     * The `DiffieHellmanGroup` class takes a well-known modp group as its argument.
     * It works the same as `DiffieHellman`, except that it does not allow changing its keys after creation.
     * In other words, it does not implement `setPublicKey()` or `setPrivateKey()` methods.
     *
     * ```js
     * const { createDiffieHellmanGroup } = await import('node:crypto');
     * const dh = createDiffieHellmanGroup('modp1');
     * ```
     * The name (e.g. `'modp1'`) is taken from [RFC 2412](https://www.rfc-editor.org/rfc/rfc2412.txt) (modp1 and 2) and [RFC 3526](https://www.rfc-editor.org/rfc/rfc3526.txt):
     * ```bash
     * $ perl -ne 'print "$1\n" if /"(modp\d+)"/' src/node_crypto_groups.h
     * modp1  #  768 bits
     * modp2  # 1024 bits
     * modp5  # 1536 bits
     * modp14 # 2048 bits
     * modp15 # etc.
     * modp16
     * modp17
     * modp18
     * ```
     * @since v0.7.5
     */
    const DiffieHellmanGroup: DiffieHellmanGroupConstructor;
    interface DiffieHellmanGroupConstructor {
        new(name: string): DiffieHellmanGroup;
        (name: string): DiffieHellmanGroup;
        readonly prototype: DiffieHellmanGroup;
    }
    type DiffieHellmanGroup = Omit<DiffieHellman, "setPublicKey" | "setPrivateKey">;
    /**
     * Creates a predefined `DiffieHellmanGroup` key exchange object. The
     * supported groups are listed in the documentation for `DiffieHellmanGroup`.
     *
     * The returned object mimics the interface of objects created by {@link createDiffieHellman}, but will not allow changing
     * the keys (with `diffieHellman.setPublicKey()`, for example). The
     * advantage of using this method is that the parties do not have to
     * generate nor exchange a group modulus beforehand, saving both processor
     * and communication time.
     *
     * Example (obtaining a shared secret):
     *
     * ```js
     * const {
     *   getDiffieHellman,
     * } = await import('node:crypto');
     * const alice = getDiffieHellman('modp14');
     * const bob = getDiffieHellman('modp14');
     *
     * alice.generateKeys();
     * bob.generateKeys();
     *
     * const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
     * const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
     *
     * // aliceSecret and bobSecret should be the same
     * console.log(aliceSecret === bobSecret);
     * ```
     * @since v0.7.5
     */
    function getDiffieHellman(groupName: string): DiffieHellmanGroup;
    /**
     * An alias for {@link getDiffieHellman}
     * @since v0.9.3
     */
    function createDiffieHellmanGroup(name: string): DiffieHellmanGroup;
    /**
     * Provides an asynchronous Password-Based Key Derivation Function 2 (PBKDF2)
     * implementation. A selected HMAC digest algorithm specified by `digest` is
     * applied to derive a key of the requested byte length (`keylen`) from the `password`, `salt` and `iterations`.
     *
     * The supplied `callback` function is called with two arguments: `err` and `derivedKey`. If an error occurs while deriving the key, `err` will be set;
     * otherwise `err` will be `null`. By default, the successfully generated `derivedKey` will be passed to the callback as a `Buffer`. An error will be
     * thrown if any of the input arguments specify invalid values or types.
     *
     * The `iterations` argument must be a number set as high as possible. The
     * higher the number of iterations, the more secure the derived key will be,
     * but will take a longer amount of time to complete.
     *
     * The `salt` should be as unique as possible. It is recommended that a salt is
     * random and at least 16 bytes long. See [NIST SP 800-132](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf) for details.
     *
     * When passing strings for `password` or `salt`, please consider `caveats when using strings as inputs to cryptographic APIs`.
     *
     * ```js
     * const {
     *   pbkdf2,
     * } = await import('node:crypto');
     *
     * pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => {
     *   if (err) throw err;
     *   console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
     * });
     * ```
     *
     * An array of supported digest functions can be retrieved using {@link getHashes}.
     *
     * This API uses libuv's threadpool, which can have surprising and
     * negative performance implications for some applications; see the `UV_THREADPOOL_SIZE` documentation for more information.
     * @since v0.5.5
     */
    function pbkdf2(
        password: BinaryLike,
        salt: BinaryLike,
        iterations: number,
        keylen: number,
        digest: string,
        callback: (err: Error | null, derivedKey: Buffer) => void,
    ): void;
    /**
     * Provides a synchronous Password-Based Key Derivation Function 2 (PBKDF2)
     * implementation. A selected HMAC digest algorithm specified by `digest` is
     * applied to derive a key of the requested byte length (`keylen`) from the `password`, `salt` and `iterations`.
     *
     * If an error occurs an `Error` will be thrown, otherwise the derived key will be
     * returned as a `Buffer`.
     *
     * The `iterations` argument must be a number set as high as possible. The
     * higher the number of iterations, the more secure the derived key will be,
     * but will take a longer amount of time to complete.
     *
     * The `salt` should be as unique as possible. It is recommended that a salt is
     * random and at least 16 bytes long. See [NIST SP 800-132](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf) for details.
     *
     * When passing strings for `password` or `salt`, please consider `caveats when using strings as inputs to cryptographic APIs`.
     *
     * ```js
     * const {
     *   pbkdf2Sync,
     * } = await import('node:crypto');
     *
     * const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512');
     * console.log(key.toString('hex'));  // '3745e48...08d59ae'
     * ```
     *
     * An array of supported digest functions can be retrieved using {@link getHashes}.
     * @since v0.9.3
     */
    function pbkdf2Sync(
        password: BinaryLike,
        salt: BinaryLike,
        iterations: number,
        keylen: number,
        digest: string,
    ): Buffer;
    /**
     * Generates cryptographically strong pseudorandom data. The `size` argument
     * is a number indicating the number of bytes to generate.
     *
     * If a `callback` function is provided, the bytes are generated asynchronously
     * and the `callback` function is invoked with two arguments: `err` and `buf`.
     * If an error occurs, `err` will be an `Error` object; otherwise it is `null`. The `buf` argument is a `Buffer` containing the generated bytes.
     *
     * ```js
     * // Asynchronous
     * const {
     *   randomBytes,
     * } = await import('node:crypto');
     *
     * randomBytes(256, (err, buf) => {
     *   if (err) throw err;
     *   console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
     * });
     * ```
     *
     * If the `callback` function is not provided, the random bytes are generated
     * synchronously and returned as a `Buffer`. An error will be thrown if
     * there is a problem generating the bytes.
     *
     * ```js
     * // Synchronous
     * const {
     *   randomBytes,
     * } = await import('node:crypto');
     *
     * const buf = randomBytes(256);
     * console.log(
     *   `${buf.length} bytes of random data: ${buf.toString('hex')}`);
     * ```
     *
     * The `crypto.randomBytes()` method will not complete until there is
     * sufficient entropy available.
     * This should normally never take longer than a few milliseconds. The only time
     * when generating the random bytes may conceivably block for a longer period of
     * time is right after boot, when the whole system is still low on entropy.
     *
     * This API uses libuv's threadpool, which can have surprising and
     * negative performance implications for some applications; see the `UV_THREADPOOL_SIZE` documentation for more information.
     *
     * The asynchronous version of `crypto.randomBytes()` is carried out in a single
     * threadpool request. To minimize threadpool task length variation, partition
     * large `randomBytes` requests when doing so as part of fulfilling a client
     * request.
     * @since v0.5.8
     * @param size The number of bytes to generate. The `size` must not be larger than `2**31 - 1`.
     * @return if the `callback` function is not provided.
     */
    function randomBytes(size: number): Buffer;
    function randomBytes(size: number, callback: (err: Error | null, buf: Buffer) => void): void;
    function pseudoRandomBytes(size: number): Buffer;
    function pseudoRandomBytes(size: number, callback: (err: Error | null, buf: Buffer) => void): void;
    /**
     * Return a random integer `n` such that `min <= n < max`.  This
     * implementation avoids [modulo bias](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Modulo_bias).
     *
     * The range (`max - min`) must be less than 2**48. `min` and `max` must
     * be [safe integers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger).
     *
     * If the `callback` function is not provided, the random integer is
     * generated synchronously.
     *
     * ```js
     * // Asynchronous
     * const {
     *   randomInt,
     * } = await import('node:crypto');
     *
     * randomInt(3, (err, n) => {
     *   if (err) throw err;
     *   console.log(`Random number chosen from (0, 1, 2): ${n}`);
     * });
     * ```
     *
     * ```js
     * // Synchronous
     * const {
     *   randomInt,
     * } = await import('node:crypto');
     *
     * const n = randomInt(3);
     * console.log(`Random number chosen from (0, 1, 2): ${n}`);
     * ```
     *
     * ```js
     * // With `min` argument
     * const {
     *   randomInt,
     * } = await import('node:crypto');
     *
     * const n = randomInt(1, 7);
     * console.log(`The dice rolled: ${n}`);
     * ```
     * @since v14.10.0, v12.19.0
     * @param [min=0] Start of random range (inclusive).
     * @param max End of random range (exclusive).
     * @param callback `function(err, n) {}`.
     */
    function randomInt(max: number): number;
    function randomInt(min: number, max: number): number;
    function randomInt(max: number, callback: (err: Error | null, value: number) => void): void;
    function randomInt(min: number, max: number, callback: (err: Error | null, value: number) => void): void;
    /**
     * Synchronous version of {@link randomFill}.
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const { randomFillSync } = await import('node:crypto');
     *
     * const buf = Buffer.alloc(10);
     * console.log(randomFillSync(buf).toString('hex'));
     *
     * randomFillSync(buf, 5);
     * console.log(buf.toString('hex'));
     *
     * // The above is equivalent to the following:
     * randomFillSync(buf, 5, 5);
     * console.log(buf.toString('hex'));
     * ```
     *
     * Any `ArrayBuffer`, `TypedArray` or `DataView` instance may be passed as`buffer`.
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const { randomFillSync } = await import('node:crypto');
     *
     * const a = new Uint32Array(10);
     * console.log(Buffer.from(randomFillSync(a).buffer,
     *                         a.byteOffset, a.byteLength).toString('hex'));
     *
     * const b = new DataView(new ArrayBuffer(10));
     * console.log(Buffer.from(randomFillSync(b).buffer,
     *                         b.byteOffset, b.byteLength).toString('hex'));
     *
     * const c = new ArrayBuffer(10);
     * console.log(Buffer.from(randomFillSync(c)).toString('hex'));
     * ```
     * @since v7.10.0, v6.13.0
     * @param buffer Must be supplied. The size of the provided `buffer` must not be larger than `2**31 - 1`.
     * @param [offset=0]
     * @param [size=buffer.length - offset]
     * @return The object passed as `buffer` argument.
     */
    function randomFillSync<T extends NodeJS.ArrayBufferView>(buffer: T, offset?: number, size?: number): T;
    /**
     * This function is similar to {@link randomBytes} but requires the first
     * argument to be a `Buffer` that will be filled. It also
     * requires that a callback is passed in.
     *
     * If the `callback` function is not provided, an error will be thrown.
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const { randomFill } = await import('node:crypto');
     *
     * const buf = Buffer.alloc(10);
     * randomFill(buf, (err, buf) => {
     *   if (err) throw err;
     *   console.log(buf.toString('hex'));
     * });
     *
     * randomFill(buf, 5, (err, buf) => {
     *   if (err) throw err;
     *   console.log(buf.toString('hex'));
     * });
     *
     * // The above is equivalent to the following:
     * randomFill(buf, 5, 5, (err, buf) => {
     *   if (err) throw err;
     *   console.log(buf.toString('hex'));
     * });
     * ```
     *
     * Any `ArrayBuffer`, `TypedArray`, or `DataView` instance may be passed as `buffer`.
     *
     * While this includes instances of `Float32Array` and `Float64Array`, this
     * function should not be used to generate random floating-point numbers. The
     * result may contain `+Infinity`, `-Infinity`, and `NaN`, and even if the array
     * contains finite numbers only, they are not drawn from a uniform random
     * distribution and have no meaningful lower or upper bounds.
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const { randomFill } = await import('node:crypto');
     *
     * const a = new Uint32Array(10);
     * randomFill(a, (err, buf) => {
     *   if (err) throw err;
     *   console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
     *     .toString('hex'));
     * });
     *
     * const b = new DataView(new ArrayBuffer(10));
     * randomFill(b, (err, buf) => {
     *   if (err) throw err;
     *   console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
     *     .toString('hex'));
     * });
     *
     * const c = new ArrayBuffer(10);
     * randomFill(c, (err, buf) => {
     *   if (err) throw err;
     *   console.log(Buffer.from(buf).toString('hex'));
     * });
     * ```
     *
     * This API uses libuv's threadpool, which can have surprising and
     * negative performance implications for some applications; see the `UV_THREADPOOL_SIZE` documentation for more information.
     *
     * The asynchronous version of `crypto.randomFill()` is carried out in a single
     * threadpool request. To minimize threadpool task length variation, partition
     * large `randomFill` requests when doing so as part of fulfilling a client
     * request.
     * @since v7.10.0, v6.13.0
     * @param buffer Must be supplied. The size of the provided `buffer` must not be larger than `2**31 - 1`.
     * @param [offset=0]
     * @param [size=buffer.length - offset]
     * @param callback `function(err, buf) {}`.
     */
    function randomFill<T extends NodeJS.ArrayBufferView>(
        buffer: T,
        callback: (err: Error | null, buf: T) => void,
    ): void;
    function randomFill<T extends NodeJS.ArrayBufferView>(
        buffer: T,
        offset: number,
        callback: (err: Error | null, buf: T) => void,
    ): void;
    function randomFill<T extends NodeJS.ArrayBufferView>(
        buffer: T,
        offset: number,
        size: number,
        callback: (err: Error | null, buf: T) => void,
    ): void;
    interface ScryptOptions {
        cost?: number | undefined;
        blockSize?: number | undefined;
        parallelization?: number | undefined;
        N?: number | undefined;
        r?: number | undefined;
        p?: number | undefined;
        maxmem?: number | undefined;
    }
    /**
     * Provides an asynchronous [scrypt](https://en.wikipedia.org/wiki/Scrypt) implementation. Scrypt is a password-based
     * key derivation function that is designed to be expensive computationally and
     * memory-wise in order to make brute-force attacks unrewarding.
     *
     * The `salt` should be as unique as possible. It is recommended that a salt is
     * random and at least 16 bytes long. See [NIST SP 800-132](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf) for details.
     *
     * When passing strings for `password` or `salt`, please consider `caveats when using strings as inputs to cryptographic APIs`.
     *
     * The `callback` function is called with two arguments: `err` and `derivedKey`. `err` is an exception object when key derivation fails, otherwise `err` is `null`. `derivedKey` is passed to the
     * callback as a `Buffer`.
     *
     * An exception is thrown when any of the input arguments specify invalid values
     * or types.
     *
     * ```js
     * const {
     *   scrypt,
     * } = await import('node:crypto');
     *
     * // Using the factory defaults.
     * scrypt('password', 'salt', 64, (err, derivedKey) => {
     *   if (err) throw err;
     *   console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
     * });
     * // Using a custom N parameter. Must be a power of two.
     * scrypt('password', 'salt', 64, { N: 1024 }, (err, derivedKey) => {
     *   if (err) throw err;
     *   console.log(derivedKey.toString('hex'));  // '3745e48...aa39b34'
     * });
     * ```
     * @since v10.5.0
     */
    function scrypt(
        password: BinaryLike,
        salt: BinaryLike,
        keylen: number,
        callback: (err: Error | null, derivedKey: Buffer) => void,
    ): void;
    function scrypt(
        password: BinaryLike,
        salt: BinaryLike,
        keylen: number,
        options: ScryptOptions,
        callback: (err: Error | null, derivedKey: Buffer) => void,
    ): void;
    /**
     * Provides a synchronous [scrypt](https://en.wikipedia.org/wiki/Scrypt) implementation. Scrypt is a password-based
     * key derivation function that is designed to be expensive computationally and
     * memory-wise in order to make brute-force attacks unrewarding.
     *
     * The `salt` should be as unique as possible. It is recommended that a salt is
     * random and at least 16 bytes long. See [NIST SP 800-132](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf) for details.
     *
     * When passing strings for `password` or `salt`, please consider `caveats when using strings as inputs to cryptographic APIs`.
     *
     * An exception is thrown when key derivation fails, otherwise the derived key is
     * returned as a `Buffer`.
     *
     * An exception is thrown when any of the input arguments specify invalid values
     * or types.
     *
     * ```js
     * const {
     *   scryptSync,
     * } = await import('node:crypto');
     * // Using the factory defaults.
     *
     * const key1 = scryptSync('password', 'salt', 64);
     * console.log(key1.toString('hex'));  // '3745e48...08d59ae'
     * // Using a custom N parameter. Must be a power of two.
     * const key2 = scryptSync('password', 'salt', 64, { N: 1024 });
     * console.log(key2.toString('hex'));  // '3745e48...aa39b34'
     * ```
     * @since v10.5.0
     */
    function scryptSync(password: BinaryLike, salt: BinaryLike, keylen: number, options?: ScryptOptions): Buffer;
    interface RsaPublicKey {
        key: KeyLike;
        padding?: number | undefined;
    }
    interface RsaPrivateKey {
        key: KeyLike;
        passphrase?: string | undefined;
        /**
         * @default 'sha1'
         */
        oaepHash?: string | undefined;
        oaepLabel?: NodeJS.TypedArray | undefined;
        padding?: number | undefined;
    }
    /**
     * Encrypts the content of `buffer` with `key` and returns a new `Buffer` with encrypted content. The returned data can be decrypted using
     * the corresponding private key, for example using {@link privateDecrypt}.
     *
     * If `key` is not a `KeyObject`, this function behaves as if `key` had been passed to {@link createPublicKey}. If it is an
     * object, the `padding` property can be passed. Otherwise, this function uses `RSA_PKCS1_OAEP_PADDING`.
     *
     * Because RSA public keys can be derived from private keys, a private key may
     * be passed instead of a public key.
     * @since v0.11.14
     */
    function publicEncrypt(
        key: RsaPublicKey | RsaPrivateKey | KeyLike,
        buffer: NodeJS.ArrayBufferView | string,
    ): Buffer;
    /**
     * Decrypts `buffer` with `key`.`buffer` was previously encrypted using
     * the corresponding private key, for example using {@link privateEncrypt}.
     *
     * If `key` is not a `KeyObject`, this function behaves as if `key` had been passed to {@link createPublicKey}. If it is an
     * object, the `padding` property can be passed. Otherwise, this function uses `RSA_PKCS1_PADDING`.
     *
     * Because RSA public keys can be derived from private keys, a private key may
     * be passed instead of a public key.
     * @since v1.1.0
     */
    function publicDecrypt(
        key: RsaPublicKey | RsaPrivateKey | KeyLike,
        buffer: NodeJS.ArrayBufferView | string,
    ): Buffer;
    /**
     * Decrypts `buffer` with `privateKey`. `buffer` was previously encrypted using
     * the corresponding public key, for example using {@link publicEncrypt}.
     *
     * If `privateKey` is not a `KeyObject`, this function behaves as if `privateKey` had been passed to {@link createPrivateKey}. If it is an
     * object, the `padding` property can be passed. Otherwise, this function uses `RSA_PKCS1_OAEP_PADDING`.
     * @since v0.11.14
     */
    function privateDecrypt(privateKey: RsaPrivateKey | KeyLike, buffer: NodeJS.ArrayBufferView | string): Buffer;
    /**
     * Encrypts `buffer` with `privateKey`. The returned data can be decrypted using
     * the corresponding public key, for example using {@link publicDecrypt}.
     *
     * If `privateKey` is not a `KeyObject`, this function behaves as if `privateKey` had been passed to {@link createPrivateKey}. If it is an
     * object, the `padding` property can be passed. Otherwise, this function uses `RSA_PKCS1_PADDING`.
     * @since v1.1.0
     */
    function privateEncrypt(privateKey: RsaPrivateKey | KeyLike, buffer: NodeJS.ArrayBufferView | string): Buffer;
    /**
     * ```js
     * const {
     *   getCiphers,
     * } = await import('node:crypto');
     *
     * console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]
     * ```
     * @since v0.9.3
     * @return An array with the names of the supported cipher algorithms.
     */
    function getCiphers(): string[];
    /**
     * ```js
     * const {
     *   getCurves,
     * } = await import('node:crypto');
     *
     * console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]
     * ```
     * @since v2.3.0
     * @return An array with the names of the supported elliptic curves.
     */
    function getCurves(): string[];
    /**
     * @since v10.0.0
     * @return `1` if and only if a FIPS compliant crypto provider is currently in use, `0` otherwise. A future semver-major release may change the return type of this API to a {boolean}.
     */
    function getFips(): 1 | 0;
    /**
     * Enables the FIPS compliant crypto provider in a FIPS-enabled Node.js build.
     * Throws an error if FIPS mode is not available.
     * @since v10.0.0
     * @param bool `true` to enable FIPS mode.
     */
    function setFips(bool: boolean): void;
    /**
     * ```js
     * const {
     *   getHashes,
     * } = await import('node:crypto');
     *
     * console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]
     * ```
     * @since v0.9.3
     * @return An array of the names of the supported hash algorithms, such as `'RSA-SHA256'`. Hash algorithms are also called "digest" algorithms.
     */
    function getHashes(): string[];
    /**
     * The `ECDH` class is a utility for creating Elliptic Curve Diffie-Hellman (ECDH)
     * key exchanges.
     *
     * Instances of the `ECDH` class can be created using the {@link createECDH} function.
     *
     * ```js
     * import assert from 'node:assert';
     *
     * const {
     *   createECDH,
     * } = await import('node:crypto');
     *
     * // Generate Alice's keys...
     * const alice = createECDH('secp521r1');
     * const aliceKey = alice.generateKeys();
     *
     * // Generate Bob's keys...
     * const bob = createECDH('secp521r1');
     * const bobKey = bob.generateKeys();
     *
     * // Exchange and generate the secret...
     * const aliceSecret = alice.computeSecret(bobKey);
     * const bobSecret = bob.computeSecret(aliceKey);
     *
     * assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
     * // OK
     * ```
     * @since v0.11.14
     */
    class ECDH {
        private constructor();
        /**
         * Converts the EC Diffie-Hellman public key specified by `key` and `curve` to the
         * format specified by `format`. The `format` argument specifies point encoding
         * and can be `'compressed'`, `'uncompressed'` or `'hybrid'`. The supplied key is
         * interpreted using the specified `inputEncoding`, and the returned key is encoded
         * using the specified `outputEncoding`.
         *
         * Use {@link getCurves} to obtain a list of available curve names.
         * On recent OpenSSL releases, `openssl ecparam -list_curves` will also display
         * the name and description of each available elliptic curve.
         *
         * If `format` is not specified the point will be returned in `'uncompressed'` format.
         *
         * If the `inputEncoding` is not provided, `key` is expected to be a `Buffer`, `TypedArray`, or `DataView`.
         *
         * Example (uncompressing a key):
         *
         * ```js
         * const {
         *   createECDH,
         *   ECDH,
         * } = await import('node:crypto');
         *
         * const ecdh = createECDH('secp256k1');
         * ecdh.generateKeys();
         *
         * const compressedKey = ecdh.getPublicKey('hex', 'compressed');
         *
         * const uncompressedKey = ECDH.convertKey(compressedKey,
         *                                         'secp256k1',
         *                                         'hex',
         *                                         'hex',
         *                                         'uncompressed');
         *
         * // The converted key and the uncompressed public key should be the same
         * console.log(uncompressedKey === ecdh.getPublicKey('hex'));
         * ```
         * @since v10.0.0
         * @param inputEncoding The `encoding` of the `key` string.
         * @param outputEncoding The `encoding` of the return value.
         * @param [format='uncompressed']
         */
        static convertKey(
            key: BinaryLike,
            curve: string,
            inputEncoding?: BinaryToTextEncoding,
            outputEncoding?: "latin1" | "hex" | "base64" | "base64url",
            format?: "uncompressed" | "compressed" | "hybrid",
        ): Buffer | string;
        /**
         * Generates private and public EC Diffie-Hellman key values, and returns
         * the public key in the specified `format` and `encoding`. This key should be
         * transferred to the other party.
         *
         * The `format` argument specifies point encoding and can be `'compressed'` or `'uncompressed'`. If `format` is not specified, the point will be returned in`'uncompressed'` format.
         *
         * If `encoding` is provided a string is returned; otherwise a `Buffer` is returned.
         * @since v0.11.14
         * @param encoding The `encoding` of the return value.
         * @param [format='uncompressed']
         */
        generateKeys(): Buffer;
        generateKeys(encoding: BinaryToTextEncoding, format?: ECDHKeyFormat): string;
        /**
         * Computes the shared secret using `otherPublicKey` as the other
         * party's public key and returns the computed shared secret. The supplied
         * key is interpreted using specified `inputEncoding`, and the returned secret
         * is encoded using the specified `outputEncoding`.
         * If the `inputEncoding` is not
         * provided, `otherPublicKey` is expected to be a `Buffer`, `TypedArray`, or `DataView`.
         *
         * If `outputEncoding` is given a string will be returned; otherwise a `Buffer` is returned.
         *
         * `ecdh.computeSecret` will throw an`ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY` error when `otherPublicKey` lies outside of the elliptic curve. Since `otherPublicKey` is
         * usually supplied from a remote user over an insecure network,
         * be sure to handle this exception accordingly.
         * @since v0.11.14
         * @param inputEncoding The `encoding` of the `otherPublicKey` string.
         * @param outputEncoding The `encoding` of the return value.
         */
        computeSecret(otherPublicKey: NodeJS.ArrayBufferView): Buffer;
        computeSecret(otherPublicKey: string, inputEncoding: BinaryToTextEncoding): Buffer;
        computeSecret(otherPublicKey: NodeJS.ArrayBufferView, outputEncoding: BinaryToTextEncoding): string;
        computeSecret(
            otherPublicKey: string,
            inputEncoding: BinaryToTextEncoding,
            outputEncoding: BinaryToTextEncoding,
        ): string;
        /**
         * If `encoding` is specified, a string is returned; otherwise a `Buffer` is
         * returned.
         * @since v0.11.14
         * @param encoding The `encoding` of the return value.
         * @return The EC Diffie-Hellman in the specified `encoding`.
         */
        getPrivateKey(): Buffer;
        getPrivateKey(encoding: BinaryToTextEncoding): string;
        /**
         * The `format` argument specifies point encoding and can be `'compressed'` or `'uncompressed'`. If `format` is not specified the point will be returned in`'uncompressed'` format.
         *
         * If `encoding` is specified, a string is returned; otherwise a `Buffer` is
         * returned.
         * @since v0.11.14
         * @param encoding The `encoding` of the return value.
         * @param [format='uncompressed']
         * @return The EC Diffie-Hellman public key in the specified `encoding` and `format`.
         */
        getPublicKey(encoding?: null, format?: ECDHKeyFormat): Buffer;
        getPublicKey(encoding: BinaryToTextEncoding, format?: ECDHKeyFormat): string;
        /**
         * Sets the EC Diffie-Hellman private key.
         * If `encoding` is provided, `privateKey` is expected
         * to be a string; otherwise `privateKey` is expected to be a `Buffer`, `TypedArray`, or `DataView`.
         *
         * If `privateKey` is not valid for the curve specified when the `ECDH` object was
         * created, an error is thrown. Upon setting the private key, the associated
         * public point (key) is also generated and set in the `ECDH` object.
         * @since v0.11.14
         * @param encoding The `encoding` of the `privateKey` string.
         */
        setPrivateKey(privateKey: NodeJS.ArrayBufferView): void;
        setPrivateKey(privateKey: string, encoding: BinaryToTextEncoding): void;
    }
    /**
     * Creates an Elliptic Curve Diffie-Hellman (`ECDH`) key exchange object using a
     * predefined curve specified by the `curveName` string. Use {@link getCurves} to obtain a list of available curve names. On recent
     * OpenSSL releases, `openssl ecparam -list_curves` will also display the name
     * and description of each available elliptic curve.
     * @since v0.11.14
     */
    function createECDH(curveName: string): ECDH;
    /**
     * This function compares the underlying bytes that represent the given `ArrayBuffer`, `TypedArray`, or `DataView` instances using a constant-time
     * algorithm.
     *
     * This function does not leak timing information that
     * would allow an attacker to guess one of the values. This is suitable for
     * comparing HMAC digests or secret values like authentication cookies or [capability urls](https://www.w3.org/TR/capability-urls/).
     *
     * `a` and `b` must both be `Buffer`s, `TypedArray`s, or `DataView`s, and they
     * must have the same byte length. An error is thrown if `a` and `b` have
     * different byte lengths.
     *
     * If at least one of `a` and `b` is a `TypedArray` with more than one byte per
     * entry, such as `Uint16Array`, the result will be computed using the platform
     * byte order.
     *
     * **When both of the inputs are `Float32Array`s or `Float64Array`s, this function might return unexpected results due to IEEE 754**
     * **encoding of floating-point numbers. In particular, neither `x === y` nor `Object.is(x, y)` implies that the byte representations of two floating-point**
     * **numbers `x` and `y` are equal.**
     *
     * Use of `crypto.timingSafeEqual` does not guarantee that the _surrounding_ code
     * is timing-safe. Care should be taken to ensure that the surrounding code does
     * not introduce timing vulnerabilities.
     * @since v6.6.0
     */
    function timingSafeEqual(a: NodeJS.ArrayBufferView, b: NodeJS.ArrayBufferView): boolean;
    type KeyType = "rsa" | "rsa-pss" | "dsa" | "ec" | "ed25519" | "ed448" | "x25519" | "x448";
    type KeyFormat = "pem" | "der" | "jwk";
    interface BasePrivateKeyEncodingOptions<T extends KeyFormat> {
        format: T;
        cipher?: string | undefined;
        passphrase?: string | undefined;
    }
    interface KeyPairKeyObjectResult {
        publicKey: KeyObject;
        privateKey: KeyObject;
    }
    interface ED25519KeyPairKeyObjectOptions {}
    interface ED448KeyPairKeyObjectOptions {}
    interface X25519KeyPairKeyObjectOptions {}
    interface X448KeyPairKeyObjectOptions {}
    interface ECKeyPairKeyObjectOptions {
        /**
         * Name of the curve to use
         */
        namedCurve: string;
        /**
         * Must be `'named'` or `'explicit'`. Default: `'named'`.
         */
        paramEncoding?: "explicit" | "named" | undefined;
    }
    interface RSAKeyPairKeyObjectOptions {
        /**
         * Key size in bits
         */
        modulusLength: number;
        /**
         * Public exponent
         * @default 0x10001
         */
        publicExponent?: number | undefined;
    }
    interface RSAPSSKeyPairKeyObjectOptions {
        /**
         * Key size in bits
         */
        modulusLength: number;
        /**
         * Public exponent
         * @default 0x10001
         */
        publicExponent?: number | undefined;
        /**
         * Name of the message digest
         */
        hashAlgorithm?: string;
        /**
         * Name of the message digest used by MGF1
         */
        mgf1HashAlgorithm?: string;
        /**
         * Minimal salt length in bytes
         */
        saltLength?: string;
    }
    interface DSAKeyPairKeyObjectOptions {
        /**
         * Key size in bits
         */
        modulusLength: number;
        /**
         * Size of q in bits
         */
        divisorLength: number;
    }
    interface RSAKeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> {
        /**
         * Key size in bits
         */
        modulusLength: number;
        /**
         * Public exponent
         * @default 0x10001
         */
        publicExponent?: number | undefined;
        publicKeyEncoding: {
            type: "pkcs1" | "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "pkcs1" | "pkcs8";
        };
    }
    interface RSAPSSKeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> {
        /**
         * Key size in bits
         */
        modulusLength: number;
        /**
         * Public exponent
         * @default 0x10001
         */
        publicExponent?: number | undefined;
        /**
         * Name of the message digest
         */
        hashAlgorithm?: string;
        /**
         * Name of the message digest used by MGF1
         */
        mgf1HashAlgorithm?: string;
        /**
         * Minimal salt length in bytes
         */
        saltLength?: string;
        publicKeyEncoding: {
            type: "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "pkcs8";
        };
    }
    interface DSAKeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> {
        /**
         * Key size in bits
         */
        modulusLength: number;
        /**
         * Size of q in bits
         */
        divisorLength: number;
        publicKeyEncoding: {
            type: "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "pkcs8";
        };
    }
    interface ECKeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> extends ECKeyPairKeyObjectOptions {
        publicKeyEncoding: {
            type: "pkcs1" | "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "sec1" | "pkcs8";
        };
    }
    interface ED25519KeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> {
        publicKeyEncoding: {
            type: "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "pkcs8";
        };
    }
    interface ED448KeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> {
        publicKeyEncoding: {
            type: "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "pkcs8";
        };
    }
    interface X25519KeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> {
        publicKeyEncoding: {
            type: "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "pkcs8";
        };
    }
    interface X448KeyPairOptions<PubF extends KeyFormat, PrivF extends KeyFormat> {
        publicKeyEncoding: {
            type: "spki";
            format: PubF;
        };
        privateKeyEncoding: BasePrivateKeyEncodingOptions<PrivF> & {
            type: "pkcs8";
        };
    }
    interface KeyPairSyncResult<T1 extends string | Buffer, T2 extends string | Buffer> {
        publicKey: T1;
        privateKey: T2;
    }
    /**
     * Generates a new asymmetric key pair of the given `type`. RSA, RSA-PSS, DSA, EC,
     * Ed25519, Ed448, X25519, X448, and DH are currently supported.
     *
     * If a `publicKeyEncoding` or `privateKeyEncoding` was specified, this function
     * behaves as if `keyObject.export()` had been called on its result. Otherwise,
     * the respective part of the key is returned as a `KeyObject`.
     *
     * When encoding public keys, it is recommended to use `'spki'`. When encoding
     * private keys, it is recommended to use `'pkcs8'` with a strong passphrase,
     * and to keep the passphrase confidential.
     *
     * ```js
     * const {
     *   generateKeyPairSync,
     * } = await import('node:crypto');
     *
     * const {
     *   publicKey,
     *   privateKey,
     * } = generateKeyPairSync('rsa', {
     *   modulusLength: 4096,
     *   publicKeyEncoding: {
     *     type: 'spki',
     *     format: 'pem',
     *   },
     *   privateKeyEncoding: {
     *     type: 'pkcs8',
     *     format: 'pem',
     *     cipher: 'aes-256-cbc',
     *     passphrase: 'top secret',
     *   },
     * });
     * ```
     *
     * The return value `{ publicKey, privateKey }` represents the generated key pair.
     * When PEM encoding was selected, the respective key will be a string, otherwise
     * it will be a buffer containing the data encoded as DER.
     * @since v10.12.0
     * @param type Must be `'rsa'`, `'rsa-pss'`, `'dsa'`, `'ec'`, `'ed25519'`, `'ed448'`, `'x25519'`, `'x448'`, or `'dh'`.
     */
    function generateKeyPairSync(
        type: "rsa",
        options: RSAKeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "rsa",
        options: RSAKeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "rsa",
        options: RSAKeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "rsa",
        options: RSAKeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "rsa", options: RSAKeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    function generateKeyPairSync(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "rsa-pss", options: RSAPSSKeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    function generateKeyPairSync(
        type: "dsa",
        options: DSAKeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "dsa",
        options: DSAKeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "dsa",
        options: DSAKeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "dsa",
        options: DSAKeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "dsa", options: DSAKeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    function generateKeyPairSync(
        type: "ec",
        options: ECKeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "ec",
        options: ECKeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "ec",
        options: ECKeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "ec",
        options: ECKeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "ec", options: ECKeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    function generateKeyPairSync(
        type: "ed25519",
        options: ED25519KeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "ed25519",
        options: ED25519KeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "ed25519",
        options: ED25519KeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "ed25519",
        options: ED25519KeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "ed25519", options?: ED25519KeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    function generateKeyPairSync(
        type: "ed448",
        options: ED448KeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "ed448",
        options: ED448KeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "ed448",
        options: ED448KeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "ed448",
        options: ED448KeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "ed448", options?: ED448KeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    function generateKeyPairSync(
        type: "x25519",
        options: X25519KeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "x25519",
        options: X25519KeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "x25519",
        options: X25519KeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "x25519",
        options: X25519KeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "x25519", options?: X25519KeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    function generateKeyPairSync(
        type: "x448",
        options: X448KeyPairOptions<"pem", "pem">,
    ): KeyPairSyncResult<string, string>;
    function generateKeyPairSync(
        type: "x448",
        options: X448KeyPairOptions<"pem", "der">,
    ): KeyPairSyncResult<string, Buffer>;
    function generateKeyPairSync(
        type: "x448",
        options: X448KeyPairOptions<"der", "pem">,
    ): KeyPairSyncResult<Buffer, string>;
    function generateKeyPairSync(
        type: "x448",
        options: X448KeyPairOptions<"der", "der">,
    ): KeyPairSyncResult<Buffer, Buffer>;
    function generateKeyPairSync(type: "x448", options?: X448KeyPairKeyObjectOptions): KeyPairKeyObjectResult;
    /**
     * Generates a new asymmetric key pair of the given `type`. RSA, RSA-PSS, DSA, EC,
     * Ed25519, Ed448, X25519, X448, and DH are currently supported.
     *
     * If a `publicKeyEncoding` or `privateKeyEncoding` was specified, this function
     * behaves as if `keyObject.export()` had been called on its result. Otherwise,
     * the respective part of the key is returned as a `KeyObject`.
     *
     * It is recommended to encode public keys as `'spki'` and private keys as `'pkcs8'` with encryption for long-term storage:
     *
     * ```js
     * const {
     *   generateKeyPair,
     * } = await import('node:crypto');
     *
     * generateKeyPair('rsa', {
     *   modulusLength: 4096,
     *   publicKeyEncoding: {
     *     type: 'spki',
     *     format: 'pem',
     *   },
     *   privateKeyEncoding: {
     *     type: 'pkcs8',
     *     format: 'pem',
     *     cipher: 'aes-256-cbc',
     *     passphrase: 'top secret',
     *   },
     * }, (err, publicKey, privateKey) => {
     *   // Handle errors and use the generated key pair.
     * });
     * ```
     *
     * On completion, `callback` will be called with `err` set to `undefined` and `publicKey` / `privateKey` representing the generated key pair.
     *
     * If this method is invoked as its `util.promisify()` ed version, it returns
     * a `Promise` for an `Object` with `publicKey` and `privateKey` properties.
     * @since v10.12.0
     * @param type Must be `'rsa'`, `'rsa-pss'`, `'dsa'`, `'ec'`, `'ed25519'`, `'ed448'`, `'x25519'`, `'x448'`, or `'dh'`.
     */
    function generateKeyPair(
        type: "rsa",
        options: RSAKeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "rsa",
        options: RSAKeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "rsa",
        options: RSAKeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "rsa",
        options: RSAKeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "rsa",
        options: RSAKeyPairKeyObjectOptions,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    function generateKeyPair(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "rsa-pss",
        options: RSAPSSKeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "rsa-pss",
        options: RSAPSSKeyPairKeyObjectOptions,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    function generateKeyPair(
        type: "dsa",
        options: DSAKeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "dsa",
        options: DSAKeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "dsa",
        options: DSAKeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "dsa",
        options: DSAKeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "dsa",
        options: DSAKeyPairKeyObjectOptions,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    function generateKeyPair(
        type: "ec",
        options: ECKeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "ec",
        options: ECKeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "ec",
        options: ECKeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "ec",
        options: ECKeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "ec",
        options: ECKeyPairKeyObjectOptions,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    function generateKeyPair(
        type: "ed25519",
        options: ED25519KeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "ed25519",
        options: ED25519KeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "ed25519",
        options: ED25519KeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "ed25519",
        options: ED25519KeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "ed25519",
        options: ED25519KeyPairKeyObjectOptions | undefined,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    function generateKeyPair(
        type: "ed448",
        options: ED448KeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "ed448",
        options: ED448KeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "ed448",
        options: ED448KeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "ed448",
        options: ED448KeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "ed448",
        options: ED448KeyPairKeyObjectOptions | undefined,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    function generateKeyPair(
        type: "x25519",
        options: X25519KeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "x25519",
        options: X25519KeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "x25519",
        options: X25519KeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "x25519",
        options: X25519KeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "x25519",
        options: X25519KeyPairKeyObjectOptions | undefined,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    function generateKeyPair(
        type: "x448",
        options: X448KeyPairOptions<"pem", "pem">,
        callback: (err: Error | null, publicKey: string, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "x448",
        options: X448KeyPairOptions<"pem", "der">,
        callback: (err: Error | null, publicKey: string, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "x448",
        options: X448KeyPairOptions<"der", "pem">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: string) => void,
    ): void;
    function generateKeyPair(
        type: "x448",
        options: X448KeyPairOptions<"der", "der">,
        callback: (err: Error | null, publicKey: Buffer, privateKey: Buffer) => void,
    ): void;
    function generateKeyPair(
        type: "x448",
        options: X448KeyPairKeyObjectOptions | undefined,
        callback: (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => void,
    ): void;
    namespace generateKeyPair {
        function __promisify__(
            type: "rsa",
            options: RSAKeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "rsa",
            options: RSAKeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "rsa",
            options: RSAKeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "rsa",
            options: RSAKeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(type: "rsa", options: RSAKeyPairKeyObjectOptions): Promise<KeyPairKeyObjectResult>;
        function __promisify__(
            type: "rsa-pss",
            options: RSAPSSKeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "rsa-pss",
            options: RSAPSSKeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "rsa-pss",
            options: RSAPSSKeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "rsa-pss",
            options: RSAPSSKeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "rsa-pss",
            options: RSAPSSKeyPairKeyObjectOptions,
        ): Promise<KeyPairKeyObjectResult>;
        function __promisify__(
            type: "dsa",
            options: DSAKeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "dsa",
            options: DSAKeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "dsa",
            options: DSAKeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "dsa",
            options: DSAKeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(type: "dsa", options: DSAKeyPairKeyObjectOptions): Promise<KeyPairKeyObjectResult>;
        function __promisify__(
            type: "ec",
            options: ECKeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "ec",
            options: ECKeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "ec",
            options: ECKeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "ec",
            options: ECKeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(type: "ec", options: ECKeyPairKeyObjectOptions): Promise<KeyPairKeyObjectResult>;
        function __promisify__(
            type: "ed25519",
            options: ED25519KeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "ed25519",
            options: ED25519KeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "ed25519",
            options: ED25519KeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "ed25519",
            options: ED25519KeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "ed25519",
            options?: ED25519KeyPairKeyObjectOptions,
        ): Promise<KeyPairKeyObjectResult>;
        function __promisify__(
            type: "ed448",
            options: ED448KeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "ed448",
            options: ED448KeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "ed448",
            options: ED448KeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "ed448",
            options: ED448KeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(type: "ed448", options?: ED448KeyPairKeyObjectOptions): Promise<KeyPairKeyObjectResult>;
        function __promisify__(
            type: "x25519",
            options: X25519KeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "x25519",
            options: X25519KeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "x25519",
            options: X25519KeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "x25519",
            options: X25519KeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "x25519",
            options?: X25519KeyPairKeyObjectOptions,
        ): Promise<KeyPairKeyObjectResult>;
        function __promisify__(
            type: "x448",
            options: X448KeyPairOptions<"pem", "pem">,
        ): Promise<{
            publicKey: string;
            privateKey: string;
        }>;
        function __promisify__(
            type: "x448",
            options: X448KeyPairOptions<"pem", "der">,
        ): Promise<{
            publicKey: string;
            privateKey: Buffer;
        }>;
        function __promisify__(
            type: "x448",
            options: X448KeyPairOptions<"der", "pem">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: string;
        }>;
        function __promisify__(
            type: "x448",
            options: X448KeyPairOptions<"der", "der">,
        ): Promise<{
            publicKey: Buffer;
            privateKey: Buffer;
        }>;
        function __promisify__(type: "x448", options?: X448KeyPairKeyObjectOptions): Promise<KeyPairKeyObjectResult>;
    }
    /**
     * Calculates and returns the signature for `data` using the given private key and
     * algorithm. If `algorithm` is `null` or `undefined`, then the algorithm is
     * dependent upon the key type (especially Ed25519 and Ed448).
     *
     * If `key` is not a `KeyObject`, this function behaves as if `key` had been
     * passed to {@link createPrivateKey}. If it is an object, the following
     * additional properties can be passed:
     *
     * If the `callback` function is provided this function uses libuv's threadpool.
     * @since v12.0.0
     */
    function sign(
        algorithm: string | null | undefined,
        data: NodeJS.ArrayBufferView,
        key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput,
    ): Buffer;
    function sign(
        algorithm: string | null | undefined,
        data: NodeJS.ArrayBufferView,
        key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput,
        callback: (error: Error | null, data: Buffer) => void,
    ): void;
    /**
     * Verifies the given signature for `data` using the given key and algorithm. If `algorithm` is `null` or `undefined`, then the algorithm is dependent upon the
     * key type (especially Ed25519 and Ed448).
     *
     * If `key` is not a `KeyObject`, this function behaves as if `key` had been
     * passed to {@link createPublicKey}. If it is an object, the following
     * additional properties can be passed:
     *
     * The `signature` argument is the previously calculated signature for the `data`.
     *
     * Because public keys can be derived from private keys, a private key or a public
     * key may be passed for `key`.
     *
     * If the `callback` function is provided this function uses libuv's threadpool.
     * @since v12.0.0
     */
    function verify(
        algorithm: string | null | undefined,
        data: NodeJS.ArrayBufferView,
        key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
        signature: NodeJS.ArrayBufferView,
    ): boolean;
    function verify(
        algorithm: string | null | undefined,
        data: NodeJS.ArrayBufferView,
        key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
        signature: NodeJS.ArrayBufferView,
        callback: (error: Error | null, result: boolean) => void,
    ): void;
    /**
     * Computes the Diffie-Hellman secret based on a `privateKey` and a `publicKey`.
     * Both keys must have the same `asymmetricKeyType`, which must be one of `'dh'` (for Diffie-Hellman), `'ec'` (for ECDH), `'x448'`, or `'x25519'` (for ECDH-ES).
     * @since v13.9.0, v12.17.0
     */
    function diffieHellman(options: { privateKey: KeyObject; publicKey: KeyObject }): Buffer;
    /**
     * A utility for creating one-shot hash digests of data. It can be faster than the object-based `crypto.createHash()` when hashing a smaller amount of data
     * (<= 5MB) that's readily available. If the data can be big or if it is streamed, it's still recommended to use `crypto.createHash()` instead. The `algorithm`
     * is dependent on the available algorithms supported by the version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc. On recent releases
     * of OpenSSL, `openssl list -digest-algorithms` will display the available digest algorithms.
     *
     * Example:
     *
     * ```js
     * import crypto from 'node:crypto';
     * import { Buffer } from 'node:buffer';
     *
     * // Hashing a string and return the result as a hex-encoded string.
     * const string = 'Node.js';
     * // 10b3493287f831e81a438811a1ffba01f8cec4b7
     * console.log(crypto.hash('sha1', string));
     *
     * // Encode a base64-encoded string into a Buffer, hash it and return
     * // the result as a buffer.
     * const base64 = 'Tm9kZS5qcw==';
     * // <Buffer 10 b3 49 32 87 f8 31 e8 1a 43 88 11 a1 ff ba 01 f8 ce c4 b7>
     * console.log(crypto.hash('sha1', Buffer.from(base64, 'base64'), 'buffer'));
     * ```
     * @since v21.7.0, v20.12.0
     * @param data When `data` is a string, it will be encoded as UTF-8 before being hashed. If a different input encoding is desired for a string input, user
     *             could encode the string into a `TypedArray` using either `TextEncoder` or `Buffer.from()` and passing the encoded `TypedArray` into this API instead.
     * @param [outputEncoding='hex'] [Encoding](https://nodejs.org/docs/latest-v22.x/api/buffer.html#buffers-and-character-encodings) used to encode the returned digest.
     */
    function hash(algorithm: string, data: BinaryLike, outputEncoding?: BinaryToTextEncoding): string;
    function hash(algorithm: string, data: BinaryLike, outputEncoding: "buffer"): Buffer;
    function hash(
        algorithm: string,
        data: BinaryLike,
        outputEncoding?: BinaryToTextEncoding | "buffer",
    ): string | Buffer;
    type CipherMode = "cbc" | "ccm" | "cfb" | "ctr" | "ecb" | "gcm" | "ocb" | "ofb" | "stream" | "wrap" | "xts";
    interface CipherInfoOptions {
        /**
         * A test key length.
         */
        keyLength?: number | undefined;
        /**
         * A test IV length.
         */
        ivLength?: number | undefined;
    }
    interface CipherInfo {
        /**
         * The name of the cipher.
         */
        name: string;
        /**
         * The nid of the cipher.
         */
        nid: number;
        /**
         * The block size of the cipher in bytes.
         * This property is omitted when mode is 'stream'.
         */
        blockSize?: number | undefined;
        /**
         * The expected or default initialization vector length in bytes.
         * This property is omitted if the cipher does not use an initialization vector.
         */
        ivLength?: number | undefined;
        /**
         * The expected or default key length in bytes.
         */
        keyLength: number;
        /**
         * The cipher mode.
         */
        mode: CipherMode;
    }
    /**
     * Returns information about a given cipher.
     *
     * Some ciphers accept variable length keys and initialization vectors. By default,
     * the `crypto.getCipherInfo()` method will return the default values for these
     * ciphers. To test if a given key length or iv length is acceptable for given
     * cipher, use the `keyLength` and `ivLength` options. If the given values are
     * unacceptable, `undefined` will be returned.
     * @since v15.0.0
     * @param nameOrNid The name or nid of the cipher to query.
     */
    function getCipherInfo(nameOrNid: string | number, options?: CipherInfoOptions): CipherInfo | undefined;
    /**
     * HKDF is a simple key derivation function defined in RFC 5869\. The given `ikm`, `salt` and `info` are used with the `digest` to derive a key of `keylen` bytes.
     *
     * The supplied `callback` function is called with two arguments: `err` and `derivedKey`. If an errors occurs while deriving the key, `err` will be set;
     * otherwise `err` will be `null`. The successfully generated `derivedKey` will
     * be passed to the callback as an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). An error will be thrown if any
     * of the input arguments specify invalid values or types.
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const {
     *   hkdf,
     * } = await import('node:crypto');
     *
     * hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => {
     *   if (err) throw err;
     *   console.log(Buffer.from(derivedKey).toString('hex'));  // '24156e2...5391653'
     * });
     * ```
     * @since v15.0.0
     * @param digest The digest algorithm to use.
     * @param ikm The input keying material. Must be provided but can be zero-length.
     * @param salt The salt value. Must be provided but can be zero-length.
     * @param info Additional info value. Must be provided but can be zero-length, and cannot be more than 1024 bytes.
     * @param keylen The length of the key to generate. Must be greater than 0. The maximum allowable value is `255` times the number of bytes produced by the selected digest function (e.g. `sha512`
     * generates 64-byte hashes, making the maximum HKDF output 16320 bytes).
     */
    function hkdf(
        digest: string,
        irm: BinaryLike | KeyObject,
        salt: BinaryLike,
        info: BinaryLike,
        keylen: number,
        callback: (err: Error | null, derivedKey: ArrayBuffer) => void,
    ): void;
    /**
     * Provides a synchronous HKDF key derivation function as defined in RFC 5869\. The
     * given `ikm`, `salt` and `info` are used with the `digest` to derive a key of `keylen` bytes.
     *
     * The successfully generated `derivedKey` will be returned as an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
     *
     * An error will be thrown if any of the input arguments specify invalid values or
     * types, or if the derived key cannot be generated.
     *
     * ```js
     * import { Buffer } from 'node:buffer';
     * const {
     *   hkdfSync,
     * } = await import('node:crypto');
     *
     * const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64);
     * console.log(Buffer.from(derivedKey).toString('hex'));  // '24156e2...5391653'
     * ```
     * @since v15.0.0
     * @param digest The digest algorithm to use.
     * @param ikm The input keying material. Must be provided but can be zero-length.
     * @param salt The salt value. Must be provided but can be zero-length.
     * @param info Additional info value. Must be provided but can be zero-length, and cannot be more than 1024 bytes.
     * @param keylen The length of the key to generate. Must be greater than 0. The maximum allowable value is `255` times the number of bytes produced by the selected digest function (e.g. `sha512`
     * generates 64-byte hashes, making the maximum HKDF output 16320 bytes).
     */
    function hkdfSync(
        digest: string,
        ikm: BinaryLike | KeyObject,
        salt: BinaryLike,
        info: BinaryLike,
        keylen: number,
    ): ArrayBuffer;
    interface SecureHeapUsage {
        /**
         * The total allocated secure heap size as specified using the `--secure-heap=n` command-line flag.
         */
        total: number;
        /**
         * The minimum allocation from the secure heap as specified using the `--secure-heap-min` command-line flag.
         */
        min: number;
        /**
         * The total number of bytes currently allocated from the secure heap.
         */
        used: number;
        /**
         * The calculated ratio of `used` to `total` allocated bytes.
         */
        utilization: number;
    }
    /**
     * @since v15.6.0
     */
    function secureHeapUsed(): SecureHeapUsage;
    interface RandomUUIDOptions {
        /**
         * By default, to improve performance,
         * Node.js will pre-emptively generate and persistently cache enough
         * random data to generate up to 128 random UUIDs. To generate a UUID
         * without using the cache, set `disableEntropyCache` to `true`.
         *
         * @default `false`
         */
        disableEntropyCache?: boolean | undefined;
    }
    type UUID = `${string}-${string}-${string}-${string}-${string}`;
    /**
     * Generates a random [RFC 4122](https://www.rfc-editor.org/rfc/rfc4122.txt) version 4 UUID. The UUID is generated using a
     * cryptographic pseudorandom number generator.
     * @since v15.6.0, v14.17.0
     */
    function randomUUID(options?: RandomUUIDOptions): UUID;
    interface X509CheckOptions {
        /**
         * @default 'always'
         */
        subject?: "always" | "default" | "never";
        /**
         * @default true
         */
        wildcards?: boolean;
        /**
         * @default true
         */
        partialWildcards?: boolean;
        /**
         * @default false
         */
        multiLabelWildcards?: boolean;
        /**
         * @default false
         */
        singleLabelSubdomains?: boolean;
    }
    /**
     * Encapsulates an X509 certificate and provides read-only access to
     * its information.
     *
     * ```js
     * const { X509Certificate } = await import('node:crypto');
     *
     * const x509 = new X509Certificate('{... pem encoded cert ...}');
     *
     * console.log(x509.subject);
     * ```
     * @since v15.6.0
     */
    class X509Certificate {
        /**
         * Will be \`true\` if this is a Certificate Authority (CA) certificate.
         * @since v15.6.0
         */
        readonly ca: boolean;
        /**
         * The SHA-1 fingerprint of this certificate.
         *
         * Because SHA-1 is cryptographically broken and because the security of SHA-1 is
         * significantly worse than that of algorithms that are commonly used to sign
         * certificates, consider using `x509.fingerprint256` instead.
         * @since v15.6.0
         */
        readonly fingerprint: string;
        /**
         * The SHA-256 fingerprint of this certificate.
         * @since v15.6.0
         */
        readonly fingerprint256: string;
        /**
         * The SHA-512 fingerprint of this certificate.
         *
         * Because computing the SHA-256 fingerprint is usually faster and because it is
         * only half the size of the SHA-512 fingerprint, `x509.fingerprint256` may be
         * a better choice. While SHA-512 presumably provides a higher level of security in
         * general, the security of SHA-256 matches that of most algorithms that are
         * commonly used to sign certificates.
         * @since v17.2.0, v16.14.0
         */
        readonly fingerprint512: string;
        /**
         * The complete subject of this certificate.
         * @since v15.6.0
         */
        readonly subject: string;
        /**
         * The subject alternative name specified for this certificate.
         *
         * This is a comma-separated list of subject alternative names. Each entry begins
         * with a string identifying the kind of the subject alternative name followed by
         * a colon and the value associated with the entry.
         *
         * Earlier versions of Node.js incorrectly assumed that it is safe to split this
         * property at the two-character sequence `', '` (see [CVE-2021-44532](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44532)). However,
         * both malicious and legitimate certificates can contain subject alternative names
         * that include this sequence when represented as a string.
         *
         * After the prefix denoting the type of the entry, the remainder of each entry
         * might be enclosed in quotes to indicate that the value is a JSON string literal.
         * For backward compatibility, Node.js only uses JSON string literals within this
         * property when necessary to avoid ambiguity. Third-party code should be prepared
         * to handle both possible entry formats.
         * @since v15.6.0
         */
        readonly subjectAltName: string | undefined;
        /**
         * A textual representation of the certificate's authority information access
         * extension.
         *
         * This is a line feed separated list of access descriptions. Each line begins with
         * the access method and the kind of the access location, followed by a colon and
         * the value associated with the access location.
         *
         * After the prefix denoting the access method and the kind of the access location,
         * the remainder of each line might be enclosed in quotes to indicate that the
         * value is a JSON string literal. For backward compatibility, Node.js only uses
         * JSON string literals within this property when necessary to avoid ambiguity.
         * Third-party code should be prepared to handle both possible entry formats.
         * @since v15.6.0
         */
        readonly infoAccess: string | undefined;
        /**
         * An array detailing the key usages for this certificate.
         * @since v15.6.0
         */
        readonly keyUsage: string[];
        /**
         * The issuer identification included in this certificate.
         * @since v15.6.0
         */
        readonly issuer: string;
        /**
         * The issuer certificate or `undefined` if the issuer certificate is not
         * available.
         * @since v15.9.0
         */
        readonly issuerCertificate?: X509Certificate | undefined;
        /**
         * The public key `KeyObject` for this certificate.
         * @since v15.6.0
         */
        readonly publicKey: KeyObject;
        /**
         * A `Buffer` containing the DER encoding of this certificate.
         * @since v15.6.0
         */
        readonly raw: Buffer;
        /**
         * The serial number of this certificate.
         *
         * Serial numbers are assigned by certificate authorities and do not uniquely
         * identify certificates. Consider using `x509.fingerprint256` as a unique
         * identifier instead.
         * @since v15.6.0
         */
        readonly serialNumber: string;
        /**
         * The date/time from which this certificate is considered valid.
         * @since v15.6.0
         */
        readonly validFrom: string;
        /**
         * The date/time from which this certificate is valid, encapsulated in a `Date` object.
         * @since v22.10.0
         */
        readonly validFromDate: Date;
        /**
         * The date/time until which this certificate is considered valid.
         * @since v15.6.0
         */
        readonly validTo: string;
        /**
         * The date/time until which this certificate is valid, encapsulated in a `Date` object.
         * @since v22.10.0
         */
        readonly validToDate: Date;
        constructor(buffer: BinaryLike);
        /**
         * Checks whether the certificate matches the given email address.
         *
         * If the `'subject'` option is undefined or set to `'default'`, the certificate
         * subject is only considered if the subject alternative name extension either does
         * not exist or does not contain any email addresses.
         *
         * If the `'subject'` option is set to `'always'` and if the subject alternative
         * name extension either does not exist or does not contain a matching email
         * address, the certificate subject is considered.
         *
         * If the `'subject'` option is set to `'never'`, the certificate subject is never
         * considered, even if the certificate contains no subject alternative names.
         * @since v15.6.0
         * @return Returns `email` if the certificate matches, `undefined` if it does not.
         */
        checkEmail(email: string, options?: Pick<X509CheckOptions, "subject">): string | undefined;
        /**
         * Checks whether the certificate matches the given host name.
         *
         * If the certificate matches the given host name, the matching subject name is
         * returned. The returned name might be an exact match (e.g., `foo.example.com`)
         * or it might contain wildcards (e.g., `*.example.com`). Because host name
         * comparisons are case-insensitive, the returned subject name might also differ
         * from the given `name` in capitalization.
         *
         * If the `'subject'` option is undefined or set to `'default'`, the certificate
         * subject is only considered if the subject alternative name extension either does
         * not exist or does not contain any DNS names. This behavior is consistent with [RFC 2818](https://www.rfc-editor.org/rfc/rfc2818.txt) ("HTTP Over TLS").
         *
         * If the `'subject'` option is set to `'always'` and if the subject alternative
         * name extension either does not exist or does not contain a matching DNS name,
         * the certificate subject is considered.
         *
         * If the `'subject'` option is set to `'never'`, the certificate subject is never
         * considered, even if the certificate contains no subject alternative names.
         * @since v15.6.0
         * @return Returns a subject name that matches `name`, or `undefined` if no subject name matches `name`.
         */
        checkHost(name: string, options?: X509CheckOptions): string | undefined;
        /**
         * Checks whether the certificate matches the given IP address (IPv4 or IPv6).
         *
         * Only [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280.txt) `iPAddress` subject alternative names are considered, and they
         * must match the given `ip` address exactly. Other subject alternative names as
         * well as the subject field of the certificate are ignored.
         * @since v15.6.0
         * @return Returns `ip` if the certificate matches, `undefined` if it does not.
         */
        checkIP(ip: string): string | undefined;
        /**
         * Checks whether this certificate was issued by the given `otherCert`.
         * @since v15.6.0
         */
        checkIssued(otherCert: X509Certificate): boolean;
        /**
         * Checks whether the public key for this certificate is consistent with
         * the given private key.
         * @since v15.6.0
         * @param privateKey A private key.
         */
        checkPrivateKey(privateKey: KeyObject): boolean;
        /**
         * There is no standard JSON encoding for X509 certificates. The`toJSON()` method returns a string containing the PEM encoded
         * certificate.
         * @since v15.6.0
         */
        toJSON(): string;
        /**
         * Returns information about this certificate using the legacy `certificate object` encoding.
         * @since v15.6.0
         */
        toLegacyObject(): PeerCertificate;
        /**
         * Returns the PEM-encoded certificate.
         * @since v15.6.0
         */
        toString(): string;
        /**
         * Verifies that this certificate was signed by the given public key.
         * Does not perform any other validation checks on the certificate.
         * @since v15.6.0
         * @param publicKey A public key.
         */
        verify(publicKey: KeyObject): boolean;
    }
    type LargeNumberLike = NodeJS.ArrayBufferView | SharedArrayBuffer | ArrayBuffer | bigint;
    interface GeneratePrimeOptions {
        add?: LargeNumberLike | undefined;
        rem?: LargeNumberLike | undefined;
        /**
         * @default false
         */
        safe?: boolean | undefined;
        bigint?: boolean | undefined;
    }
    interface GeneratePrimeOptionsBigInt extends GeneratePrimeOptions {
        bigint: true;
    }
    interface GeneratePrimeOptionsArrayBuffer extends GeneratePrimeOptions {
        bigint?: false | undefined;
    }
    /**
     * Generates a pseudorandom prime of `size` bits.
     *
     * If `options.safe` is `true`, the prime will be a safe prime -- that is, `(prime - 1) / 2` will also be a prime.
     *
     * The `options.add` and `options.rem` parameters can be used to enforce additional
     * requirements, e.g., for Diffie-Hellman:
     *
     * * If `options.add` and `options.rem` are both set, the prime will satisfy the
     * condition that `prime % add = rem`.
     * * If only `options.add` is set and `options.safe` is not `true`, the prime will
     * satisfy the condition that `prime % add = 1`.
     * * If only `options.add` is set and `options.safe` is set to `true`, the prime
     * will instead satisfy the condition that `prime % add = 3`. This is necessary
     * because `prime % add = 1` for `options.add > 2` would contradict the condition
     * enforced by `options.safe`.
     * * `options.rem` is ignored if `options.add` is not given.
     *
     * Both `options.add` and `options.rem` must be encoded as big-endian sequences
     * if given as an `ArrayBuffer`, `SharedArrayBuffer`, `TypedArray`, `Buffer`, or `DataView`.
     *
     * By default, the prime is encoded as a big-endian sequence of octets
     * in an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). If the `bigint` option is `true`, then a
     * [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) is provided.
     * @since v15.8.0
     * @param size The size (in bits) of the prime to generate.
     */
    function generatePrime(size: number, callback: (err: Error | null, prime: ArrayBuffer) => void): void;
    function generatePrime(
        size: number,
        options: GeneratePrimeOptionsBigInt,
        callback: (err: Error | null, prime: bigint) => void,
    ): void;
    function generatePrime(
        size: number,
        options: GeneratePrimeOptionsArrayBuffer,
        callback: (err: Error | null, prime: ArrayBuffer) => void,
    ): void;
    function generatePrime(
        size: number,
        options: GeneratePrimeOptions,
        callback: (err: Error | null, prime: ArrayBuffer | bigint) => void,
    ): void;
    /**
     * Generates a pseudorandom prime of `size` bits.
     *
     * If `options.safe` is `true`, the prime will be a safe prime -- that is, `(prime - 1) / 2` will also be a prime.
     *
     * The `options.add` and `options.rem` parameters can be used to enforce additional
     * requirements, e.g., for Diffie-Hellman:
     *
     * * If `options.add` and `options.rem` are both set, the prime will satisfy the
     * condition that `prime % add = rem`.
     * * If only `options.add` is set and `options.safe` is not `true`, the prime will
     * satisfy the condition that `prime % add = 1`.
     * * If only `options.add` is set and `options.safe` is set to `true`, the prime
     * will instead satisfy the condition that `prime % add = 3`. This is necessary
     * because `prime % add = 1` for `options.add > 2` would contradict the condition
     * enforced by `options.safe`.
     * * `options.rem` is ignored if `options.add` is not given.
     *
     * Both `options.add` and `options.rem` must be encoded as big-endian sequences
     * if given as an `ArrayBuffer`, `SharedArrayBuffer`, `TypedArray`, `Buffer`, or `DataView`.
     *
     * By default, the prime is encoded as a big-endian sequence of octets
     * in an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). If the `bigint` option is `true`, then a
     * [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) is provided.
     * @since v15.8.0
     * @param size The size (in bits) of the prime to generate.
     */
    function generatePrimeSync(size: number): ArrayBuffer;
    function generatePrimeSync(size: number, options: GeneratePrimeOptionsBigInt): bigint;
    function generatePrimeSync(size: number, options: GeneratePrimeOptionsArrayBuffer): ArrayBuffer;
    function generatePrimeSync(size: number, options: GeneratePrimeOptions): ArrayBuffer | bigint;
    interface CheckPrimeOptions {
        /**
         * The number of Miller-Rabin probabilistic primality iterations to perform.
         * When the value is 0 (zero), a number of checks is used that yields a false positive rate of at most `2**-64` for random input.
         * Care must be used when selecting a number of checks.
         * Refer to the OpenSSL documentation for the BN_is_prime_ex function nchecks options for more details.
         *
         * @default 0
         */
        checks?: number | undefined;
    }
    /**
     * Checks the primality of the `candidate`.
     * @since v15.8.0
     * @param candidate A possible prime encoded as a sequence of big endian octets of arbitrary length.
     */
    function checkPrime(value: LargeNumberLike, callback: (err: Error | null, result: boolean) => void): void;
    function checkPrime(
        value: LargeNumberLike,
        options: CheckPrimeOptions,
        callback: (err: Error | null, result: boolean) => void,
    ): void;
    /**
     * Checks the primality of the `candidate`.
     * @since v15.8.0
     * @param candidate A possible prime encoded as a sequence of big endian octets of arbitrary length.
     * @return `true` if the candidate is a prime with an error probability less than `0.25 ** options.checks`.
     */
    function checkPrimeSync(candidate: LargeNumberLike, options?: CheckPrimeOptions): boolean;
    /**
     * Load and set the `engine` for some or all OpenSSL functions (selected by flags).
     *
     * `engine` could be either an id or a path to the engine's shared library.
     *
     * The optional `flags` argument uses `ENGINE_METHOD_ALL` by default. The `flags` is a bit field taking one of or a mix of the following flags (defined in `crypto.constants`):
     *
     * * `crypto.constants.ENGINE_METHOD_RSA`
     * * `crypto.constants.ENGINE_METHOD_DSA`
     * * `crypto.constants.ENGINE_METHOD_DH`
     * * `crypto.constants.ENGINE_METHOD_RAND`
     * * `crypto.constants.ENGINE_METHOD_EC`
     * * `crypto.constants.ENGINE_METHOD_CIPHERS`
     * * `crypto.constants.ENGINE_METHOD_DIGESTS`
     * * `crypto.constants.ENGINE_METHOD_PKEY_METHS`
     * * `crypto.constants.ENGINE_METHOD_PKEY_ASN1_METHS`
     * * `crypto.constants.ENGINE_METHOD_ALL`
     * * `crypto.constants.ENGINE_METHOD_NONE`
     * @since v0.11.11
     * @param flags
     */
    function setEngine(engine: string, flags?: number): void;
    /**
     * A convenient alias for {@link webcrypto.getRandomValues}. This
     * implementation is not compliant with the Web Crypto spec, to write
     * web-compatible code use {@link webcrypto.getRandomValues} instead.
     * @since v17.4.0
     * @return Returns `typedArray`.
     */
    function getRandomValues<T extends webcrypto.BufferSource>(typedArray: T): T;
    /**
     * A convenient alias for `crypto.webcrypto.subtle`.
     * @since v17.4.0
     */
    const subtle: webcrypto.SubtleCrypto;
    /**
     * An implementation of the Web Crypto API standard.
     *
     * See the {@link https://nodejs.org/docs/latest/api/webcrypto.html Web Crypto API documentation} for details.
     * @since v15.0.0
     */
    const webcrypto: webcrypto.Crypto;
    namespace webcrypto {
        type BufferSource = ArrayBufferView | ArrayBuffer;
        type KeyFormat = "jwk" | "pkcs8" | "raw" | "spki";
        type KeyType = "private" | "public" | "secret";
        type KeyUsage =
            | "decrypt"
            | "deriveBits"
            | "deriveKey"
            | "encrypt"
            | "sign"
            | "unwrapKey"
            | "verify"
            | "wrapKey";
        type AlgorithmIdentifier = Algorithm | string;
        type HashAlgorithmIdentifier = AlgorithmIdentifier;
        type NamedCurve = string;
        type BigInteger = Uint8Array;
        interface AesCbcParams extends Algorithm {
            iv: BufferSource;
        }
        interface AesCtrParams extends Algorithm {
            counter: BufferSource;
            length: number;
        }
        interface AesDerivedKeyParams extends Algorithm {
            length: number;
        }
        interface AesGcmParams extends Algorithm {
            additionalData?: BufferSource;
            iv: BufferSource;
            tagLength?: number;
        }
        interface AesKeyAlgorithm extends KeyAlgorithm {
            length: number;
        }
        interface AesKeyGenParams extends Algorithm {
            length: number;
        }
        interface Algorithm {
            name: string;
        }
        interface EcKeyAlgorithm extends KeyAlgorithm {
            namedCurve: NamedCurve;
        }
        interface EcKeyGenParams extends Algorithm {
            namedCurve: NamedCurve;
        }
        interface EcKeyImportParams extends Algorithm {
            namedCurve: NamedCurve;
        }
        interface EcdhKeyDeriveParams extends Algorithm {
            public: CryptoKey;
        }
        interface EcdsaParams extends Algorithm {
            hash: HashAlgorithmIdentifier;
        }
        interface Ed448Params extends Algorithm {
            context?: BufferSource;
        }
        interface HkdfParams extends Algorithm {
            hash: HashAlgorithmIdentifier;
            info: BufferSource;
            salt: BufferSource;
        }
        interface HmacImportParams extends Algorithm {
            hash: HashAlgorithmIdentifier;
            length?: number;
        }
        interface HmacKeyAlgorithm extends KeyAlgorithm {
            hash: KeyAlgorithm;
            length: number;
        }
        interface HmacKeyGenParams extends Algorithm {
            hash: HashAlgorithmIdentifier;
            length?: number;
        }
        interface JsonWebKey {
            alg?: string;
            crv?: string;
            d?: string;
            dp?: string;
            dq?: string;
            e?: string;
            ext?: boolean;
            k?: string;
            key_ops?: string[];
            kty?: string;
            n?: string;
            oth?: RsaOtherPrimesInfo[];
            p?: string;
            q?: string;
            qi?: string;
            use?: string;
            x?: string;
            y?: string;
        }
        interface KeyAlgorithm {
            name: string;
        }
        interface Pbkdf2Params extends Algorithm {
            hash: HashAlgorithmIdentifier;
            iterations: number;
            salt: BufferSource;
        }
        interface RsaHashedImportParams extends Algorithm {
            hash: HashAlgorithmIdentifier;
        }
        interface RsaHashedKeyAlgorithm extends RsaKeyAlgorithm {
            hash: KeyAlgorithm;
        }
        interface RsaHashedKeyGenParams extends RsaKeyGenParams {
            hash: HashAlgorithmIdentifier;
        }
        interface RsaKeyAlgorithm extends KeyAlgorithm {
            modulusLength: number;
            publicExponent: BigInteger;
        }
        interface RsaKeyGenParams extends Algorithm {
            modulusLength: number;
            publicExponent: BigInteger;
        }
        interface RsaOaepParams extends Algorithm {
            label?: BufferSource;
        }
        interface RsaOtherPrimesInfo {
            d?: string;
            r?: string;
            t?: string;
        }
        interface RsaPssParams extends Algorithm {
            saltLength: number;
        }
        /**
         * Importing the `webcrypto` object (`import { webcrypto } from 'node:crypto'`) gives an instance of the `Crypto` class.
         * `Crypto` is a singleton that provides access to the remainder of the crypto API.
         * @since v15.0.0
         */
        interface Crypto {
            /**
             * Provides access to the `SubtleCrypto` API.
             * @since v15.0.0
             */
            readonly subtle: SubtleCrypto;
            /**
             * Generates cryptographically strong random values.
             * The given `typedArray` is filled with random values, and a reference to `typedArray` is returned.
             *
             * The given `typedArray` must be an integer-based instance of {@link NodeJS.TypedArray}, i.e. `Float32Array` and `Float64Array` are not accepted.
             *
             * An error will be thrown if the given `typedArray` is larger than 65,536 bytes.
             * @since v15.0.0
             */
            getRandomValues<T extends Exclude<NodeJS.TypedArray, Float32Array | Float64Array>>(typedArray: T): T;
            /**
             * Generates a random {@link https://www.rfc-editor.org/rfc/rfc4122.txt RFC 4122} version 4 UUID.
             * The UUID is generated using a cryptographic pseudorandom number generator.
             * @since v16.7.0
             */
            randomUUID(): UUID;
            CryptoKey: CryptoKeyConstructor;
        }
        // This constructor throws ILLEGAL_CONSTRUCTOR so it should not be newable.
        interface CryptoKeyConstructor {
            /** Illegal constructor */
            (_: { readonly _: unique symbol }): never; // Allows instanceof to work but not be callable by the user.
            readonly length: 0;
            readonly name: "CryptoKey";
            readonly prototype: CryptoKey;
        }
        /**
         * @since v15.0.0
         */
        interface CryptoKey {
            /**
             * An object detailing the algorithm for which the key can be used along with additional algorithm-specific parameters.
             * @since v15.0.0
             */
            readonly algorithm: KeyAlgorithm;
            /**
             * When `true`, the {@link CryptoKey} can be extracted using either `subtleCrypto.exportKey()` or `subtleCrypto.wrapKey()`.
             * @since v15.0.0
             */
            readonly extractable: boolean;
            /**
             * A string identifying whether the key is a symmetric (`'secret'`) or asymmetric (`'private'` or `'public'`) key.
             * @since v15.0.0
             */
            readonly type: KeyType;
            /**
             * An array of strings identifying the operations for which the key may be used.
             *
             * The possible usages are:
             * - `'encrypt'` - The key may be used to encrypt data.
             * - `'decrypt'` - The key may be used to decrypt data.
             * - `'sign'` - The key may be used to generate digital signatures.
             * - `'verify'` - The key may be used to verify digital signatures.
             * - `'deriveKey'` - The key may be used to derive a new key.
             * - `'deriveBits'` - The key may be used to derive bits.
             * - `'wrapKey'` - The key may be used to wrap another key.
             * - `'unwrapKey'` - The key may be used to unwrap another key.
             *
             * Valid key usages depend on the key algorithm (identified by `cryptokey.algorithm.name`).
             * @since v15.0.0
             */
            readonly usages: KeyUsage[];
        }
        /**
         * The `CryptoKeyPair` is a simple dictionary object with `publicKey` and `privateKey` properties, representing an asymmetric key pair.
         * @since v15.0.0
         */
        interface CryptoKeyPair {
            /**
             * A {@link CryptoKey} whose type will be `'private'`.
             * @since v15.0.0
             */
            privateKey: CryptoKey;
            /**
             * A {@link CryptoKey} whose type will be `'public'`.
             * @since v15.0.0
             */
            publicKey: CryptoKey;
        }
        /**
         * @since v15.0.0
         */
        interface SubtleCrypto {
            /**
             * Using the method and parameters specified in `algorithm` and the keying material provided by `key`,
             * `subtle.decrypt()` attempts to decipher the provided `data`. If successful,
             * the returned promise will be resolved with an `<ArrayBuffer>` containing the plaintext result.
             *
             * The algorithms currently supported include:
             *
             * - `'RSA-OAEP'`
             * - `'AES-CTR'`
             * - `'AES-CBC'`
             * - `'AES-GCM'`
             * @since v15.0.0
             */
            decrypt(
                algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams,
                key: CryptoKey,
                data: BufferSource,
            ): Promise<ArrayBuffer>;
            /**
             * Using the method and parameters specified in `algorithm` and the keying material provided by `baseKey`,
             * `subtle.deriveBits()` attempts to generate `length` bits.
             * The Node.js implementation requires that when `length` is a number it must be multiple of `8`.
             * When `length` is `null` the maximum number of bits for a given algorithm is generated. This is allowed
             * for the `'ECDH'`, `'X25519'`, and `'X448'` algorithms.
             * If successful, the returned promise will be resolved with an `<ArrayBuffer>` containing the generated data.
             *
             * The algorithms currently supported include:
             *
             * - `'ECDH'`
             * - `'X25519'`
             * - `'X448'`
             * - `'HKDF'`
             * - `'PBKDF2'`
             * @since v15.0.0
             */
            deriveBits(algorithm: EcdhKeyDeriveParams, baseKey: CryptoKey, length: number | null): Promise<ArrayBuffer>;
            deriveBits(
                algorithm: AlgorithmIdentifier | HkdfParams | Pbkdf2Params,
                baseKey: CryptoKey,
                length: number,
            ): Promise<ArrayBuffer>;
            /**
             * Using the method and parameters specified in `algorithm`, and the keying material provided by `baseKey`,
             * `subtle.deriveKey()` attempts to generate a new <CryptoKey>` based on the method and parameters in `derivedKeyAlgorithm`.
             *
             * Calling `subtle.deriveKey()` is equivalent to calling `subtle.deriveBits()` to generate raw keying material,
             * then passing the result into the `subtle.importKey()` method using the `deriveKeyAlgorithm`, `extractable`, and `keyUsages` parameters as input.
             *
             * The algorithms currently supported include:
             *
             * - `'ECDH'`
             * - `'X25519'`
             * - `'X448'`
             * - `'HKDF'`
             * - `'PBKDF2'`
             * @param keyUsages See {@link https://nodejs.org/docs/latest/api/webcrypto.html#cryptokeyusages Key usages}.
             * @since v15.0.0
             */
            deriveKey(
                algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params,
                baseKey: CryptoKey,
                derivedKeyAlgorithm:
                    | AlgorithmIdentifier
                    | AesDerivedKeyParams
                    | HmacImportParams
                    | HkdfParams
                    | Pbkdf2Params,
                extractable: boolean,
                keyUsages: readonly KeyUsage[],
            ): Promise<CryptoKey>;
            /**
             * Using the method identified by `algorithm`, `subtle.digest()` attempts to generate a digest of `data`.
             * If successful, the returned promise is resolved with an `<ArrayBuffer>` containing the computed digest.
             *
             * If `algorithm` is provided as a `<string>`, it must be one of:
             *
             * - `'SHA-1'`
             * - `'SHA-256'`
             * - `'SHA-384'`
             * - `'SHA-512'`
             *
             * If `algorithm` is provided as an `<Object>`, it must have a `name` property whose value is one of the above.
             * @since v15.0.0
             */
            digest(algorithm: AlgorithmIdentifier, data: BufferSource): Promise<ArrayBuffer>;
            /**
             * Using the method and parameters specified by `algorithm` and the keying material provided by `key`,
             * `subtle.encrypt()` attempts to encipher `data`. If successful,
             * the returned promise is resolved with an `<ArrayBuffer>` containing the encrypted result.
             *
             * The algorithms currently supported include:
             *
             * - `'RSA-OAEP'`
             * - `'AES-CTR'`
             * - `'AES-CBC'`
             * - `'AES-GCM'`
             * @since v15.0.0
             */
            encrypt(
                algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams,
                key: CryptoKey,
                data: BufferSource,
            ): Promise<ArrayBuffer>;
            /**
             * Exports the given key into the specified format, if supported.
             *
             * If the `<CryptoKey>` is not extractable, the returned promise will reject.
             *
             * When `format` is either `'pkcs8'` or `'spki'` and the export is successful,
             * the returned promise will be resolved with an `<ArrayBuffer>` containing the exported key data.
             *
             * When `format` is `'jwk'` and the export is successful, the returned promise will be resolved with a
             * JavaScript object conforming to the {@link https://tools.ietf.org/html/rfc7517 JSON Web Key} specification.
             * @param format Must be one of `'raw'`, `'pkcs8'`, `'spki'`, or `'jwk'`.
             * @returns `<Promise>` containing `<ArrayBuffer>`.
             * @since v15.0.0
             */
            exportKey(format: "jwk", key: CryptoKey): Promise<JsonWebKey>;
            exportKey(format: Exclude<KeyFormat, "jwk">, key: CryptoKey): Promise<ArrayBuffer>;
            /**
             * Using the method and parameters provided in `algorithm`,
             * `subtle.generateKey()` attempts to generate new keying material.
             * Depending the method used, the method may generate either a single `<CryptoKey>` or a `<CryptoKeyPair>`.
             *
             * The `<CryptoKeyPair>` (public and private key) generating algorithms supported include:
             *
             * - `'RSASSA-PKCS1-v1_5'`
             * - `'RSA-PSS'`
             * - `'RSA-OAEP'`
             * - `'ECDSA'`
             * - `'Ed25519'`
             * - `'Ed448'`
             * - `'ECDH'`
             * - `'X25519'`
             * - `'X448'`
             * The `<CryptoKey>` (secret key) generating algorithms supported include:
             *
             * - `'HMAC'`
             * - `'AES-CTR'`
             * - `'AES-CBC'`
             * - `'AES-GCM'`
             * - `'AES-KW'`
             * @param keyUsages See {@link https://nodejs.org/docs/latest/api/webcrypto.html#cryptokeyusages Key usages}.
             * @since v15.0.0
             */
            generateKey(
                algorithm: RsaHashedKeyGenParams | EcKeyGenParams,
                extractable: boolean,
                keyUsages: readonly KeyUsage[],
            ): Promise<CryptoKeyPair>;
            generateKey(
                algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params,
                extractable: boolean,
                keyUsages: readonly KeyUsage[],
            ): Promise<CryptoKey>;
            generateKey(
                algorithm: AlgorithmIdentifier,
                extractable: boolean,
                keyUsages: KeyUsage[],
            ): Promise<CryptoKeyPair | CryptoKey>;
            /**
             * The `subtle.importKey()` method attempts to interpret the provided `keyData` as the given `format`
             * to create a `<CryptoKey>` instance using the provided `algorithm`, `extractable`, and `keyUsages` arguments.
             * If the import is successful, the returned promise will be resolved with the created `<CryptoKey>`.
             *
             * If importing a `'PBKDF2'` key, `extractable` must be `false`.
             * @param format Must be one of `'raw'`, `'pkcs8'`, `'spki'`, or `'jwk'`.
             * @param keyUsages See {@link https://nodejs.org/docs/latest/api/webcrypto.html#cryptokeyusages Key usages}.
             * @since v15.0.0
             */
            importKey(
                format: "jwk",
                keyData: JsonWebKey,
                algorithm:
                    | AlgorithmIdentifier
                    | RsaHashedImportParams
                    | EcKeyImportParams
                    | HmacImportParams
                    | AesKeyAlgorithm,
                extractable: boolean,
                keyUsages: readonly KeyUsage[],
            ): Promise<CryptoKey>;
            importKey(
                format: Exclude<KeyFormat, "jwk">,
                keyData: BufferSource,
                algorithm:
                    | AlgorithmIdentifier
                    | RsaHashedImportParams
                    | EcKeyImportParams
                    | HmacImportParams
                    | AesKeyAlgorithm,
                extractable: boolean,
                keyUsages: KeyUsage[],
            ): Promise<CryptoKey>;
            /**
             * Using the method and parameters given by `algorithm` and the keying material provided by `key`,
             * `subtle.sign()` attempts to generate a cryptographic signature of `data`. If successful,
             * the returned promise is resolved with an `<ArrayBuffer>` containing the generated signature.
             *
             * The algorithms currently supported include:
             *
             * - `'RSASSA-PKCS1-v1_5'`
             * - `'RSA-PSS'`
             * - `'ECDSA'`
             * - `'Ed25519'`
             * - `'Ed448'`
             * - `'HMAC'`
             * @since v15.0.0
             */
            sign(
                algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams | Ed448Params,
                key: CryptoKey,
                data: BufferSource,
            ): Promise<ArrayBuffer>;
            /**
             * In cryptography, "wrapping a key" refers to exporting and then encrypting the keying material.
             * The `subtle.unwrapKey()` method attempts to decrypt a wrapped key and create a `<CryptoKey>` instance.
             * It is equivalent to calling `subtle.decrypt()` first on the encrypted key data (using the `wrappedKey`, `unwrapAlgo`, and `unwrappingKey` arguments as input)
             * then passing the results in to the `subtle.importKey()` method using the `unwrappedKeyAlgo`, `extractable`, and `keyUsages` arguments as inputs.
             * If successful, the returned promise is resolved with a `<CryptoKey>` object.
             *
             * The wrapping algorithms currently supported include:
             *
             * - `'RSA-OAEP'`
             * - `'AES-CTR'`
             * - `'AES-CBC'`
             * - `'AES-GCM'`
             * - `'AES-KW'`
             *
             * The unwrapped key algorithms supported include:
             *
             * - `'RSASSA-PKCS1-v1_5'`
             * - `'RSA-PSS'`
             * - `'RSA-OAEP'`
             * - `'ECDSA'`
             * - `'Ed25519'`
             * - `'Ed448'`
             * - `'ECDH'`
             * - `'X25519'`
             * - `'X448'`
             * - `'HMAC'`
             * - `'AES-CTR'`
             * - `'AES-CBC'`
             * - `'AES-GCM'`
             * - `'AES-KW'`
             * @param format Must be one of `'raw'`, `'pkcs8'`, `'spki'`, or `'jwk'`.
             * @param keyUsages See {@link https://nodejs.org/docs/latest/api/webcrypto.html#cryptokeyusages Key usages}.
             * @since v15.0.0
             */
            unwrapKey(
                format: KeyFormat,
                wrappedKey: BufferSource,
                unwrappingKey: CryptoKey,
                unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams,
                unwrappedKeyAlgorithm:
                    | AlgorithmIdentifier
                    | RsaHashedImportParams
                    | EcKeyImportParams
                    | HmacImportParams
                    | AesKeyAlgorithm,
                extractable: boolean,
                keyUsages: KeyUsage[],
            ): Promise<CryptoKey>;
            /**
             * Using the method and parameters given in `algorithm` and the keying material provided by `key`,
             * `subtle.verify()` attempts to verify that `signature` is a valid cryptographic signature of `data`.
             * The returned promise is resolved with either `true` or `false`.
             *
             * The algorithms currently supported include:
             *
             * - `'RSASSA-PKCS1-v1_5'`
             * - `'RSA-PSS'`
             * - `'ECDSA'`
             * - `'Ed25519'`
             * - `'Ed448'`
             * - `'HMAC'`
             * @since v15.0.0
             */
            verify(
                algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams | Ed448Params,
                key: CryptoKey,
                signature: BufferSource,
                data: BufferSource,
            ): Promise<boolean>;
            /**
             * In cryptography, "wrapping a key" refers to exporting and then encrypting the keying material.
             * The `subtle.wrapKey()` method exports the keying material into the format identified by `format`,
             * then encrypts it using the method and parameters specified by `wrapAlgo` and the keying material provided by `wrappingKey`.
             * It is the equivalent to calling `subtle.exportKey()` using `format` and `key` as the arguments,
             * then passing the result to the `subtle.encrypt()` method using `wrappingKey` and `wrapAlgo` as inputs.
             * If successful, the returned promise will be resolved with an `<ArrayBuffer>` containing the encrypted key data.
             *
             * The wrapping algorithms currently supported include:
             *
             * - `'RSA-OAEP'`
             * - `'AES-CTR'`
             * - `'AES-CBC'`
             * - `'AES-GCM'`
             * - `'AES-KW'`
             * @param format Must be one of `'raw'`, `'pkcs8'`, `'spki'`, or `'jwk'`.
             * @since v15.0.0
             */
            wrapKey(
                format: KeyFormat,
                key: CryptoKey,
                wrappingKey: CryptoKey,
                wrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams,
            ): Promise<ArrayBuffer>;
        }
    }

    global {
        var crypto: typeof globalThis extends {
            crypto: infer T;
            onmessage: any;
        } ? T
            : webcrypto.Crypto;
    }
}
declare module "node:crypto" {
    export * from "crypto";
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

    3hX                       d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dl
Z
d dlmZ d dlmZ d dlmZ g dZddgZg dZ e            ai Zi Zd	 Zg d
Zg ag dZdadadQd
Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z' G d de(          Z) G d d          Z*d Z+ ed          Z,ddddZ-d  Z.d! Z/ ej0        d"          Z1 ej0        d#          Z2 ej0        d$          Z3i Z4d% Z5d Z6d&Z7d'Z8d( Z9i Z:d) Z;d* Z<d+ Z=d, Z>d- Z?	 dQd.Z@d/ ZAd0 ZBd1 ZCd2 ZDd3 ZEd4 ZFd5 ZGd6 ZHd7 ZI G d8 d9          ZJd: ZKd; ZLd< ZMd= ZN ej0        d>          ZOd? ZPdRdAZQdB ZRdC ZSdD ZTdE ZUdF ZVdG ZWdH ZXdI ZYdJ ZZdK Z[dL Z\dM Z]dN Z^dO Z_dP Z`dS )S    N)GypError)
OrderedSet)Version)
executableshared_libraryloadable_modulemac_kernel_extensionwindows_driverdependenciesexport_dependent_settings)destinationfilesinclude_dirsinputs	librariesoutputssourcesc                     | r$| dd          dv r| d d         } | r| dd          dv | t           v rdS d| v r<| dd          }|d         dk    r
|d d         }|dd          dv rdS |d	d          d
k    S dS )Nz=+?!T_is)_file_path_dirF)
path_sections)sectiontails     L/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/input.py
IsPathSectionr!   8   s      gbcclf,,#2#,  gbcclf,, -t g~~rss|8s??9D9***4BCCyF""5    )actionsconfigurationscopiesdefault_configurationr   dependencies_originalr   
postbuildsproduct_dirproduct_extensionproduct_nameproduct_prefixrulesrun_asr   standalone_static_librarysuppress_wildcardtarget_nametoolsettoolsetstype	variables)r#   all_dependent_settingsr$   r   direct_dependent_settingsr   
link_settingsr   r/   r1   r4   Fc                     |g }| |v r|S |                     |            ||                              dg           D ]}t          |||           |S )a  Return a list of all build files included into build_file_path.

  The returned list will contain build_file_path as well as all other files
  that it included, either directly or indirectly.  Note that the list may
  contain files that were included into a conditional section that evaluated
  to false and was not merged into build_file_path's dict.

  aux_data is a dict containing a key for each build file or included build
  file.  Those keys provide access to dicts whose "included" keys contain
  lists of all other files included by the build file.

  included should be left at its default None value by external callers.  It
  is used for recursion.

  The returned list will not contain any duplicate entries.  Each build file
  in the list will be relative to the current directory.
  Nincluded)appendgetGetIncludedBuildFiles)build_file_pathaux_datar:   included_build_files       r    r=   r=      ss    & (""OOO$$$'8<<ZLL G G18XFFFFOr"   c                    t          j        |           }t          |t           j                  sJ |j        }t          |          dk    sJ |d         }t          |t           j                  sJ t          |j        g           S )zReturn the eval of a gyp file.
  The gyp file is restricted to dictionaries and lists only, and
  repeated keys are not allowed.
  Note that this is slower than eval() is.
     r   )	astparse
isinstanceModulebodylenExpr	CheckNodevalue)
file_contentssyntax_treec1c2s       r    CheckedEvalrP      sy     )M**Kk3:.....		Br77a<<<<	ABb#(#####RXr"""r"   c           	         t          | t          j                  ri }t          | j        | j                  D ]\  }}t          |t          j                  sJ |j        }||v rQt          d|z   dz   t          t          |          dz             z   dz   d                    |          z   dz             t          |          }|
                    |           t          ||          ||<   |S t          | t          j                  rrg }t!          | j                  D ]Y\  }}t          |          }|
                    t          |                     |
                    t          ||                     Z|S t          | t          j                  r| j        S t%          dd                    |          z   dz   t          |           z             )	NzKey 'z' repeated at level rB   z with key path '.'zUnknown AST node at key path 'z': )rE   rC   DictzipkeysvaluesStrr   r   reprrH   joinlistr;   rJ   List	enumerateelts	TypeError)	nodekeypathdictkeyrK   kpchildrenindexchilds	            r    rJ   rJ      s   $!! 
di55 	- 	-JCc37+++++%Cd{{,- 3w<<!+,,- )	)
 hhw''( 
   gBIIcNNN!%,,DII	D#(	#	# 
%di00 	2 	2LE5gBIId5kk"""OOIeR001111	D#'	"	" 
v
,sxx/@/@@5H4PT::U
 
 	
r"   c                    | |v r||          S t           j                            |           r$t          | d                                          }n&t          |  dt          j                     d          d }	 |rt          |          }nt          |di id           }nK# t          $ r
}| |_
         d }~wt          $ r)}t          j
                            |d| z               d }~ww xY wt          |          t           urt          d| z            ||| <   i || <   d|vs|d         sc	 |rt#          || ||||           nt#          || ||d |           n6# t          $ r)}t          j
                            |d	| z               d }~ww xY w|S )
Nutf-8)encodingz not found (cwd: )__builtins__zwhile reading z%%s does not evaluate to a dictionary.
skip_includeszwhile reading includes of )ospathexistsopenreadr   getcwdrP   evalSyntaxErrorfilename	ExceptiongypcommonExceptionAppendr4   rb   LoadBuildFileIncludesIntoDict)	r>   datar?   includes	is_targetcheckbuild_file_contentsbuild_file_dataes	            r    LoadOneBuildFiler      s   $O$$	w~~o&& L"?WEEEJJLL/JJBIKKJJJKKKO
 	T)*=>>OO"#68LdSSO   $

   
""1&6&HIII
 OD((>PQQQ+D "H_ o--__5U-
	 
-#_dHhPU    .#_dHdE    	 	 	J&&//A
 
 
 
		 s<   9%B 
C')B11
C'>$C""C')+E 
F$FFc                    g }||                     |           d| v r}| d         D ]q}t          j                            t          j                            t          j                            |          |                    }|                    |           r| d= |D ]|}d||         vrg ||         d<   ||         d                             |           t          j        t          j	        d|           t          | t          |||d d|          ||           }|                                 D ]Y\  }	}
t          |
          t          u rt          |
|||d |           0t          |
          t           u rt#          |
||||           Zd S )Nr}   r:   zLoading Included File: '%s'F)extendrn   ro   normpathrZ   dirnamer;   rx   DebugOutputDEBUG_INCLUDES
MergeDictsr   itemsr4   rb   r{   r[   LoadBuildFileIncludesIntoList)subdictsubdict_pathr|   r?   r}   r   
includes_listincluderelative_includekvs              r    r{   r{     s    MX&&&Wz* 	3 	3G  "w//RW__\::GDD    
  !12222J ! 
 
Xl33313H\":.z*11':::*,I7SSSWdHdE5II		
 	
 	
 	
 

 R R177d??)!\44QVWWWW
!WW__)!\45QQQ	R Rr"   c           	          | D ]V}t          |          t          u rt          ||||d |           -t          |          t          u rt	          |||||           Wd S N)r4   rb   r{   r[   r   )sublistsublist_pathr|   r?   r   items         r    r   r   9  s~     U U::)lD(D%
 
 
 
 $ZZ4

)$dHeTTT
U Ur"   c                 h   d| v r| d         }g }|D ]}d|v rd|vr|                     |            t          r|                    ddg          }ndg}d|v r|d= t          |          dk    rf|dd          D ];}t          j                            |          }||d<   |                     |           <|d         |d<   |                     |           || d<   d| v rS| d         D ]L}t          |          t          u r2|dd          D ]'}t          |          t          u rt          |           (Kd S d S )Ntargetsr2   r3   targetr   rB   
conditions)r;   multiple_toolsetsr<   rH   rx   simple_copydeepcopyr4   r[   rb   ProcessToolsetsInDict)	r|   target_listnew_target_listr   r3   build
new_target	conditioncondition_dicts	            r    r   r   E  s   D9o! 	/ 	/F F""z'?'?&&v...  
&!::j8*==$:V##:&8}}q  %abb\ 7 7E!$!9!9&!A!AJ,1Jy)#**:6666$,QKy!&&v...)Ytl+ 	> 	>II$&&&/m > >NN++t33-n=== 	> 	>r"   c                    |rbt           j                            |t          j                            |                     }|dk    rd|d<   n|                    dd          |d<   d|v r'| |d         v rdS |d                             |            t          j        t           j	        d|            t          | |||d	|          }	||	d
<   d|	v rt          | dz             t          | |          }
g |	d<   |
D ]Z}t           j                            |t          j                            |                     }|	d         
                    |           [t          |	           t          |	t           ||            t          |	           d
|	v rd|	vrt          d| z            d}
|
t#          |	d                   k     rn|	d         |
         }t           j                            |	d
                   }t)          ||| |            ||	d         |
<   |
dz
  }
|
t#          |	d                   k     n|	d
= g }d|	v rU|	d         D ]L}d|vr|d         D ]<}|
                    t           j                            | |d           d                    =M|rT|D ]O}	 t-          ||||||||           # t.          $ r)}t           j                            |d| z              d }~ww xY wd S | |fS )N rR   DEPTH\/target_build_filesFzLoading Target Build File '%s'T_DEPTHincluded_filesz$ must not contain included_files keytarget_defaultsr   z'Unable to find targets in build file %sr   rB   r   z while loading dependencies of %s)rx   ry   RelativePathrn   ro   r   replaceaddr   r   r   r   r=   r;   r   #ProcessVariablesAndConditionsInDictPHASE_EARLYrH   r   r   r   
ResolveTargetLoadTargetBuildFilerw   rz   )r>   r|   r?   r5   r}   depthr   load_dependenciesdr   r:   
included_fileincluded_relativerf   old_target_dictnew_target_dictr   target_dict
dependencyr   s                       r    r   r   j  s    
 6 
J##E27???+K+KLL77!$Ig!"4!5!5Ig t##d#78885
!"&&777O<o   'x4 O
 !&OH ?**)OOPPP$_h??H(*O$%! D D
  J3327???;;
 
 	()001BCCCC /*** (i   /*** O++O++DVWWWc/)45555 .i8?O!o66 12 O 
/?
 
 
 1@OI&u-QJE! c/)45555& 
-. LO##*95 	 	K[00).9 
 

##J,,_j$OOPQR   

  /& 	 	J
#%	 	 	 	  
 
 

**9OK   	
	 	$  ..s   J%%
K/$KKc           
         	 t          j         t           j        t           j                   |                                 D ]\  }}|t	                      |<   t          |           t
          |t          t          ||||d          }	|	s|	S |	\  }}
t          	                    |          }|||
fS # t          $ r-}t          j        
                    d|z             Y d}~dS d}~wt          $ rS}t          d|t          j                   t          t!          j                    t          j                   Y d}~dS d}~ww xY w)zWrapper around LoadTargetBuildFile for parallel processing.

     This wrapper is used when LoadTargetBuildFile is executed in
     a worker process.
  Fzgyp: %s
Nz
Exception:)file)signalSIGINTSIG_IGNr   globalsSetGeneratorGlobalsr   per_process_dataper_process_aux_datapopr   sysstderrwriterw   print	traceback
format_exc)
global_flagsr>   r5   r}   r   r   generator_input_inforc   rK   resultr   r   r   s
                r    CallLoadTargetBuildFiler     s^   %
fmV^444 ',,.. 	# 	#JC"GIIcNN0111$ 	
 	
  	M*0',
 +..??  ,??   
q)))ttttt   
lACJ////
i"$$3:6666ttttts+   BB- 	#B- -
D?7"C
D?,AD::D?c                       e Zd ZdS )ParallelProcessingErrorN__name__
__module____qualname__ r"   r    r   r   +  s        Dr"   r   c                       e Zd ZdZd Zd ZdS )
ParallelStatea  Class to keep track of state when processing input files in parallel.

  If build files are loaded in parallel, use this to keep track of
  state during farming out and processing parallel jobs. It's stored
  in a global so that the callback function can have access to it.
  c                     d | _         d | _        d | _        d| _        t	                      | _        g | _        d| _        d S )Nr   F)poolr   r|   pendingset	scheduledr   errorselfs    r    __init__zParallelState.__init__7  sB    	 	  


r"   c                    | j                                          |s;d| _        | j                                          | j                                          dS |\  }}}|| j        |<   | j        d                             |           |D ]?}|| j        vr4| j                            |           | j        	                    |           @| xj
        dz  c_
        | j                                          | j                                          dS )zJHandle the results of running LoadTargetBuildFile in another process.
    TNr   rB   )r   acquirer   notifyreleaser|   r   r   r   r;   r   )r   r   build_file_path0build_file_data0
dependencies0new_dependencys         r    LoadTargetBuildFileCallbackz)ParallelState.LoadTargetBuildFileCallbackJ  s    	
    	DJN!!###N""$$$F>D;	+]&6	"#	&'++,<===+ 	9 	9NT^33"">222!((888     r"   N)r   r   r   __doc__r   r   r   r"   r    r   r   /  s<           &! ! ! ! !r"   r   c           
      >   t                      }t          j                    |_        t	          |           |_        t
          |           |_        d|_        ||_	        	 |j        
                                 |j        s|j        r|j        rn|j        s|j                                         7|j        
                                }|xj        dz
  c_        t                      d         t                      d         t                      d         d}	|j        s*t!          j        t!          j                              |_        |j                            t(          |	||||||f|j                   |j        |j        n-# t,          $ r }
|j                                         |
d }
~
ww xY w|j                                         |j                                         |j                                         d |_        |j        rt7          j        d           d S d S )Nr   rB   r   non_configuration_keysr   )r   r   r   )argscallback)r   	threading	Conditionr   r[   r   r   r   r   r|   r   r   waitr   r   r   multiprocessingPool	cpu_countapply_asyncr   r   KeyboardInterrupt	terminater   closerZ   r   exit)build_filesr|   r5   r}   r   r   r   parallel_stater   r   r   s              r    LoadTargetBuildFilesParallelr  _  s9    #__N(244N"&{"3"3N";//NNN# ((***) 	^-C 	# 
!. 
(--///'488::J""a'""!(?!;*1))4L*M%,YY/B%C L "& 
X&5&:?;T;V;V&W&W#++' ( (C 
, 
 
 
% ) 	^-C 	>    %%''' $$&&&N  s   D"F 
F+F&&F+z{[({[()}]rk   c                    g }d}t          |           D ]k\  }}|t          v r|                    |           |dk    r|},|t          v r6|s dS |                                t          |         k    r dS |s	||dz   fc S ldS )Nr   )r   r   rB   )r]   	LBRACKETSr;   BRACKETSr   )	input_strstackstartrf   chars        r    FindEnclosingBracketGroupr    s    EE ++ * *t9LL{{
X

 
 xxyy{{htn,,xx 
*uqy))))8r"   c                     t          |           t          u rN| rL| dk    rdS | d         dk    r| dd         } | sdS d| d         cxk    rd	k    rn n|                                 S dS )
z|Returns True if |string| is in its canonical integer form.

  The canonical form is such that str(int(string)) == string.
  0Tr   -rB   NF19)r4   strisdigit)strings    r    IsStrCanonicalIntr    s    
 F||s  	(}}tayC ! 5fQi&&&&3&&&&&~~'''5r"   zy(?P<replace>(?P<type><(?:(?:!?@?)|\|)?)(?P<command_string>[-a-zA-Z0-9_.]+)?\((?P<is_array>\s*\[?)(?P<content>.*?)(\]?)\))zy(?P<replace>(?P<type>>(?:(?:!?@?)|\|)?)(?P<command_string>[-a-zA-Z0-9_.]+)?\((?P<is_array>\s*\[?)(?P<content>.*?)(\]?)\))z|(?P<replace>(?P<type>[\^](?:(?:!?@?)|\|)?)(?P<command_string>[-a-zA-Z0-9_.]+)?\((?P<is_array>\s*\[?)(?P<content>.*?)(\]?)\))c                     t           j        dk    rUt          |           t          u r)t	          j        dd| d                   g| dd          z   } nt	          j        dd|           } | S )Nwin32z^cat ztype r   rB   )r   platformr4   r[   resub)cmds    r    FixupPlatformCommandr    sa    
|w996'7CF334s122w>CC&'3//CJr"   rB      c           	         |t           k    r
t          }d}n,|t          k    r
t          }d}n|t          k    r
t
          }d}nJ t
          |           }t          |          rt          |          S ||vr|S t          |
                    |                    }|s|S |}|                                 |D ]}	|	                                }
t          j        t          j        d|
           d|
d         v }|
d         }d	|
d         v }
|	                    d
          }|	                    d
          }t%          ||d                    \  }}||z   }|||         }||z   dz   }|dz
  }|||         }|
rBt          j                            |          }t+          ||           t-          ||||          }nt-          ||||          }|                                }d|
d         v o||k    }|s|
r)t0          j                            |          }|d
k    r|
sd }|
rt7          |          t          u r|n|                    d          }|d         }t0          j                            |          rt=          d|z            t>          s!t0          j                             ||          }nt0          j                            |          r.t>          d         }t          j!        "                    ||          }n|}t>          d         }t0          j                             |||          }t          j!        #                    |           t          j!        "                    ||          }t          j!        $                    |          }|dd          D ]}|%                    d|z             |&                                 n|rd} |
d         rtO          |          }d} t
          |          |f}!tP          )                    |!d           }"|"Xt          j        t          j        d||           d
}|dk    r]t1          j*                    }#|rt1          j+        |           tX          j        -                    t1          j*                               	 t]          j        |          }$	 t_          |$d                   }%n-# t`          $ r }&t=          d|$d         d|&          d }&~&ww xY wt
          |%1                    |$dd                              2                                }tX          j        3                                 t1          j+        |#           n7# tX          j        3                                 t1          j+        |#           w xY w|J n|rt=          d|d|d          ti          |          }	 tk          j6        |tj          j7        | |d          }'n)# tp          $ r}&t=          |&d|d|          d }&~&ww xY w|'j9        dk    rt=          d ||'j9        |fz            |'j:        ;                    d!          2                                }|tP          |!<   nUt          j        t          j        d"||           |"}n1||vr%|d#         d$v rg }n t=          d%|z   d&z   |z             ||         }ty          |tz                    r*ty          |t                    s|;                    d!          }t7          |          t          u r|D ]}(ty          |(tz                    r*ty          |(t                    s|(;                    d!          }(|d#         d'k    sBt7          |(          t          t          fvr%t=          d(|z   d)z   d*z   |(j>        j?        z             t          ||||           nBt7          |          t          t          fvr%t=          d(|z   d)z   d+z   |j>        j?        z             |rCt7          |          t          u r|d d          }nt]          j        t
          |                    }n_d
})t7          |          t          u r t          j!        A                    |          })n|})|d |         t
          |)          z   ||d          z   }|}|| k    r!t          j        t          j        d,|           nt          j        t          j        d-|           t7          |          t          u rN|rt7          |d                   t          u rnAg }*|D ]'}(|*-                    t-          |(|||                     (|*}nt-          ||||          }t7          |          t          u r7t          |          D ]&\  }+},t          |,          rt          |,          ||+<   'nt          |          rt          |          }|S ).N<>^FzMatches: %r!r4   command_string|r   rB   @r    r   z(| cannot handle absolute paths, got "%s"toplevelqualified_out_dirz%s
Tis_arrayz(Executing command '%s' in directory '%s'
pymod_do_mainz%Error importing pymod_do_mainmodule (z): zUnknown command string 'z' in 'z'.)stdoutshellcwdr   z while executing command '' in z1Call to '%s' returned exit status %d while in %s.ri   z2Had cache value for command '%s' in directory '%s'r   r$  r   zUndefined variable  in r   z	Variable z- must expand to a string or list of strings; zlist contains a zfound a z?Found only identity matches on %r, avoiding infinite recursion.zFound output %r, recursing.)Cr   early_variable_re
PHASE_LATElate_variable_rePHASE_LATELATElatelate_variable_rer  r  intr[   finditerreverse	groupdictrx   r   DEBUG_VARIABLESr  endr  r   r   ProcessListFiltersInDictExpandVariablesstriprn   ro   r   r4   splitisabsr   generator_filelist_pathsrZ   ry   r   EnsureDirExistsWriteOnDiffr   r   rt   cached_command_resultsr<   rs   chdirr   r;   shlex
__import__ImportErrorDoMainrstripr   r  
subprocessrunPIPErw   
returncoder-  decoderE   bytes	__class__r   #ProcessVariablesAndConditionsInListEncodePOSIXShellListr]   )-inputphaser5   
build_filevariable_reexpansion_symbolr
  matchesoutputmatch_groupmatchrun_commandr%  	file_list
replace_startreplace_endc_startc_endreplacementcontents_startcontents_endcontentsprocessed_variablesexpand_to_listbuild_file_dir
contents_listro   r)  rel_build_file_dirr*  fi	use_shell	cache_keycached_valueoldwdparsed_contents	py_moduler   r   r   encoded_replacement
new_outputrf   outstrs-                                                r    r?  r?    s
   '	*		&	.	 	 *E

I## 9~~ y(( ;''	2233G 
F
 OO V V%%''+]EBBB U6]*/0 5=(	 $)))44
!ooi00 5Y}~~5NOO% $e+  
k 9: '014"Q^L89  	O"%/":":9"E"E$X/BCCC&x8KZXXHH 'x	:NNH >>## f
-J){2J 		&) 		&  W__Z88N##I#
 "&  J	2(,X$(>(>HHHNNSVDWDWM'*Kw}}[)) 
YIKWXXX+ 
1w||NK@@7==00 87
CH),)@)@&* *&& *8&$<=P$Q!w||$57I;WW
**4000*11$GGK
&&t,,A"122& 
$ 
$
####
GGIIII
 p	2IZ  
">>!	 X7I155iFFL#'>"	   !!_44 IKKE% 1000HOOBIKK000(*/+h*?*?(2?13E(F(FII*   "*(5DQ5G5G5G!L# # 
 '*%,,_QRR-@AA' ' &(( $  &2222# I"()>>8885    4H==H
!+$#-?"+ ."'" " " %   & qq(((JJ8   (1,,&O'):JGH   #)-"6"6w"?"?"F"F"H"HK4?&y11'H"	   + y((B<:-- #%KK"-86AJN   (1k5)) 	6*[#2N2N 	6%,,W55K$$# 

 

dE** 0:dC3H3H 0;;w//D|s**tDzz#s/K/K"#"#IJ -- .1	2   
0UIz
 
 
 
 +

sCj
0
0AB  '0	1  
  	 K  D(($QQQ S%5%566 #%K  D(( '*j&E&Ek&R&R##&1# ~
~&-@)A)AAF;<<DXX 
 		
P	
 	
 	
 	
 	+-JFSSS<<4 

$$vay//T11 
"  D%%'eY
KK    $$VUIzJJF F||t&v.. 	, 	,ME6 (( 
, #Fu
	, 
6	"	" VMsH   U$R:9U:
S$SS$$?U4V
:#W
X(W??Xc           	         t          |           t          urt          |dz             t          |           dk     r;t          |dz   | d         z   dz   t	          t          |                     z             d}d}|t          |           k     r| |         }| |dz            }t          |          t
          ur$t          | d| dt          |                     t          |           |dz   k    rkt          | |dz                      t
          u rL| |dz            }	|d	z   }|t          |           k    r(t          | d| d
t          |           |z
   d          nd}	|dz   }|t
          |||	|||          }|t          |           k     |S )z]Returns the dict that should be used or None if the result was
  that nothing should be used.z must be a listr  r(  r   z  must be at least length 2, not NrB   z' must be followed by a dictionary, not    z has z unexpected trailing items)r4   r[   r   rH   r  rb   EvalSingleCondition)
r   conditions_keyrW  r5   rX  ro  r   	cond_expr	true_dict
false_dicts
             r    
EvalConditionr  [  s    Id""~(99:::
9~~ 
l
 1
1 #i..!!	
"
 
 	
 	
A
F
c)nn

aL	a!e$		??$&&! ) )I ) )I) )  
 y>>AE!!d9QU+;&<&<&D&D"1q5)JAAC	NN""% F F	 F F9~~)F F F   # JAA>(9j%J F) c)nn

0 Mr"   c                    t          | |||          }t          |          t          t          fvrt	          d|j        j        z             	 |t          v rt          |         }nt          |dd          }|t          |<   i t          d}t          |||          r|S |S # t          $ rW}	t          dt          |	j        d                   |	j
        ||	j        fz  |	j        |	j        |	j        |	j
                  }
|
d}	~	wt"          $ r:}	t$          j                            |	d| d	|            t+          |	          d}	~	ww xY w)
zMReturns true_dict if cond_expr evaluates to true, and false_dict
  otherwise.CVariable expansion in this context permits str and int only, found z<string>rt   )rl   r   z9%s while evaluating condition '%s' in %s at character %d.r   Nzwhile evaluating condition 'r0  )r?  r4   r  r8  
ValueErrorrS  r   cached_conditions_astscompiler   rt   ru   r   textoffsetrv   lineno	NameErrorrx   ry   rz   r   )r}  r~  r  rW  r5   rX  cond_expr_expandedast_codeenvr   syntax_errors              r    r{  r{    s    )E9jQQSz11
 *3
4
 
 	
!777-.@AHH1:vFFH9A"#56!00#y)) 	 	 	 	"
"%afQi..!&*ah!O
P
J
H
H
F

 
    
""
P+=PPJPP	
 	
 	
 qkks,   
AB B 
E(AC::
E5D<<Ec                     |t           k    rd}n|t          k    rd}n|t          k    rd S J || vrd S | |         }| |= |D ];}t          |||||          }|$t	          ||||           t          | |||           <d S )Nr   target_conditions)r   r4  r6  r  r   r   )the_dictrW  r5   rX  r|  conditions_listr   
merge_dicts           r    ProcessConditionsInDictr    s    " 
%	*		,	.	 	 X%%~.O $ E E	"~ui
 

 ! 
0E9j
 
 
 
xZDDDE Er"   c                     |                                 D ]0\  }}t          |          t          t          t          fv r|| d|z   <   1d S )Nr   )r   r4   r  r8  r[   )r5   r  rc   rK   s       r    LoadAutomaticVariablesFromDictr    sR     nn&& ) )
U;;3T***#(IcCi ) )r"   c                 &   |                     di                                           D ]g\  }}t          |          t          t          t
          fvr)|                    d          r"|d d         }|| v rM|dk    r||v r||         }n|}|| |<   hd S )Nr5   %r   )r<   r   r4   r  r8  r[   endswith)r5   r  the_dict_keyrc   rK   
variable_names         r    LoadVariablesFromVariablesDictr    s     ll;3399;; ) )
U;;sC...<< 	 HM	)){**}/H/H !/M#(	-  #) )r"   c                    |                                 }t          ||            d| v r>| d                                         D ]
\  }}|||<   t          | d         |||d           t	          || |           |                                 D ]w\  }}|dk    rlt          |          t          u rVt          ||||          }t          |          t          t          fvr"t          d|j
        j        z   dz   |z             || |<   x|                                 }t          ||            t	          || |           t          | |||           |                                 }t          ||            t	          || |           |                                 D ]\  }}|dk    st          |          t          u r"t          |          t          u rt          |||||           Lt          |          t          u rt          ||||           ut          |          t          ur"t!          d|j
        j        z   dz   |z             dS )zHandle all variable and command expansion and conditional evaluation.

  This function is the public entry point for all variable expansions and
  conditional evaluations.  The variables_in dictionary will not be modified
  by this function.
  r5   r  z for 
Unknown type N)copyr  r   r   r  r4   r  r?  r8  r  rS  r   r  rb   r[   rT  r_   )	r  rW  variables_inrX  r  r5   rc   rK   expandeds	            r    r   r     s    !!##I"9h777h
 #;/5577 	# 	#JC"IcNN 	,[!5)Z	
 	
 	
 #9hEEEnn&& % %
U+$u++"4"4&ueY
KKHH~~c3Z// %(12  	   %HSM !!##I"9h777"9hEEED HeY
CCC !!##I"9h777"9hEEE nn&& X X
U +e!3!3;;$ 
0uiS
 
 
 
 %[[D
 
 
 
0uiTTTT
%[[
#
#Oeo.FFPSVVWWW $#X Xr"   c                    d}|t          |           k     rN| |         }t          |          t          u rt          ||||           nt          |          t          u rt          ||||           nt          |          t          u rt          ||||          }t          |          t          t          fv r|| |<   nt          |          t          u r|| ||dz   <   |t          |          z
  }t          d|j
        j        z   dz   |z             t          |          t          ur"t          d|j
        j        z   dz   |z             |dz   }|t          |           k     Ld S d S )Nr   rB   zIVariable expansion in this context permits strings and lists only, found z at r  z
 at index )
rH   r4   rb   r   r[   rT  r  r?  r8  r  rS  r   r_   )the_listrW  r5   rX  rf   r   r  s          r    rT  rT  |  s   
E
#h--

:: 
0eY
SSSS
$ZZ4

/eY
SSSS
$ZZ3

&tUIzJJHH~~#s++"*h4''.6*+X&  +(12  	   $ZZs
"
"$."99LH5P  
 	? #h--





r"   c                     i }| d         D ]i}| |                              dg           D ]J}t          j                            ||d         |d                   }||v rt	          d|z             |||<   Kj|S )ay  Builds a dict mapping fully-qualified target names to their target dicts.

  |data| is a dict mapping loaded build files by pathname relative to the
  current directory.  Values in |data| are build file contents.  For each
  |data| value with a "targets" key, the value of the "targets" key is taken
  as a list containing target dicts.  Each target's fully-qualified name is
  constructed from the pathname of the build file (|data| key) and its
  "target_name" property.  These fully-qualified names are used as the keys
  in the returned dict.  These keys provide access to the target dicts,
  the dicts in the "targets" lists.
  r   r   r1   r2   z!Duplicate target definitions for )r<   rx   ry   QualifiedTargetr   )r|   r   rX  r   r1   s        r    BuildTargetsDictr    s     G/0 * *
:&**9b99 	* 	*F*44F=16)3D K g%%B[PQQQ#)GK  
	* Nr"   c                    d t           D             }|                                 D ]\  }}t          j                            |          }|d         }|D ]}|                    |g           }t
          |          D ]\  }}	t          j                            ||	|          \  }
}}t          s|}t          j        	                    |
||          }
|
||<   |dk    r+|
|d         vr!t          d|
z   dz   |z   dz   |z   dz             dS )	a  Make dependency links fully-qualified relative to the current directory.

  |targets| is a dict mapping fully-qualified target names to their target
  dicts.  For each target in this dict, keys known to contain dependency
  links are examined, and any dependencies referenced will be rewritten
  so that they are fully-qualified and relative to the current directory.
  All rewritten dependencies are suitable for use as keys to |targets| or a
  similar dict.
  c                 "    g | ]}d D ]}||z   
S )r   r$  r   r   ).0depops      r    
<listcomp>z'QualifyDependencies.<locals>.<listcomp>  s=       . 46b   r"   r2   r   zFound r2   of z, but not in dependenciesN)dependency_sectionsr   rx   ry   	BuildFiler<   r]   r   r   r  r   )r   all_dependency_sectionsr   r   target_build_filer2   dependency_keyr   rf   r  dep_file
dep_targetdep_toolsetr   s                 r    QualifyDependenciesr    sy    /    '}}  J0088i(5 	 	N&??>2>>L'55 
 

s47J4L4L%sG5 51*k ) *")K Z77j+ 
 '1U#
 #n44"+n*EEE" $% ! )) !	!
 !! 6
6  %
	 r"   c           	         |                                  D ]k\  }}t          j                            |          }t          D ]=}|                    |g           }d}|t
          |          k     rt          j                            ||                   \  }}	}
|	dk    r|
dk    r|dz   }O||k    rt          d|z   dz   |z   dz             ||= |dz
  }||         d         }|D ]}t          |                    dd	                    r&|d
         }
|	d|
hvr5|d         }|
d|hvrDt          j        
                    ||
|          }|dz   }|                    ||           |dz   }|t
          |          k     ?mdS )
a  Expands dependencies specified as build_file:*.

  For each target in |targets|, examines sections containing links to other
  targets.  If any such section contains a link of the form build_file:*, it
  is taken as a wildcard link, and is expanded to list each target in
  build_file.  The |data| dict provides access to build file dicts.

  Any target that does not wish to be included by wildcard can provide an
  optional "suppress_wildcard" key in its target dict.  When present and
  true, a wildcard dependency link will not include such targets.

  All dependency names, including the keys to |targets| and the values in each
  dependency list, must be qualified when this function is called.
  r   *rB   zFound wildcard in r  z referring to same build filer   r0   Fr1   r2   N)r   rx   ry   r  r  r<   rH   ParseQualifiedTargetr   r8  r  insert)r   r|   r   r   r  r  r   rf   dependency_build_filedependency_targetdependency_toolsetdependency_target_dictsdependency_target_dictdependency_target_namedependency_target_toolsetr   s                   r    ExpandWildcardDependenciesr    s      '}} =" ="J00881 ;	" ;	"N&??>2>>L E#l++++
 J33L4GHH	)%&$++0Bc0I0I!AIE(,=== #,() ! !! :	:   !'	
 +//D*Ei*P'.E ; ;*1556I5QQRR ! -CM-R*)#7M1NNN 0Fy0Q-*38Q2RRR !$!;!;-.1" "J
 "AIE ''z::::	k #l++++
;	"=" ="r"   c                 $    i fd| D             S )zARemoves duplicate elements from items, keeping the first element.c                 D    g | ]}|v                     ||          S r   
setdefault)r  r   seens     r    r  zUnify.<locals>.<listcomp>?  s,    BBBaATMMDOOAq!!MMMr"   r   )r   r  s    @r    Unifyr  <  s"    
DBBBB5BBBBr"   c                     |                                  D ]9\  }}t          D ],}|                    |g           }|rt          |          ||<   -:dS )zRMakes sure every dependency appears only once in all targets's dependency
  lists.N)r   r  r<   r  )r   r1   r   r  r   s        r    RemoveDuplicateDependenciesr  B  st     %,MMOO B B [1 	B 	BN&??>2>>L 
B.3L.A.AN+	BB Br"   c                 (    i fd| D             S )zRemoves item from items.c                 H    g | ]}|k                         ||          S r   r  )r  r   r   ress     r    r  zFilter.<locals>.<listcomp>O  s,    ===Q199CNN1a  999r"   r   )r   r   r  s    `@r    Filterr  L  s&    
C=====%====r"   c                    |                                  D ]u\  }}t          D ]h}|                    |g           }|rN|D ]K}||k    rC| |                             di                               dd          rt          ||          ||<   LivdS )zYRemove self dependencies from targets that have the prune_self_dependency
  variable set.r5   prune_self_dependencyr   Nr   r  r<   r  r   r1   r   r  r   ts         r    RemoveSelfDependenciesr  R  s     %,MMOO   [1 	 	N&??>2>>L 	
%  AK''
["--4a88 (
 7=(+7 7N3	 r"   c                 N   |                                  D ]\  }}t          D ]}|                    |g           }|rh|D ]e}|                    dd          dk    rI| |                             di                               dd          rt          ||         |          ||<   fdS )zURemove dependencies having the 'link_dependency' attribute from the 'none'
  targets.r4   Nnoner5   link_dependencyr   r  r  s         r    %RemoveLinkDependenciesFromNoneTargetsr  d  s     %,MMOO 	 	 [1 	 	N&??>2>>L 
%  A"vt44>>"1:>>+r::>>?PRSTT :@ +N ;Q; ;K7
		 	r"   c                   |    e Zd ZdZ G d de          Zd Zd Zd Zd Z	dd	Z
dd
ZddZddZ
	 ddZd Zd ZdS )DependencyGraphNodez

  Attributes:
    ref: A reference to an object that this DependencyGraphNode represents.
    dependencies: List of DependencyGraphNodes on which this one depends.
    dependents: List of DependencyGraphNodes that depend on this one.
  c                       e Zd ZdS )%DependencyGraphNode.CircularExceptionNr   r   r"   r    CircularExceptionr  |  s        r"   r  c                 0    || _         g | _        g | _        d S r   )refr   
dependents)r   r  s     r    r   zDependencyGraphNode.__init__  s    r"   c                     d| j         z  S )Nz<DependencyGraphNode: %r>r  r   s    r    __repr__zDependencyGraphNode.__repr__  s    *TX55r"   c                 t   t                      }d }t          | j        d d          |          }|ry|                                }|                    |j                   t          |j        |          D ]2}d}t          |j        |          D ]}|j        |vrd} n|r||gz
  }3|yt          |          S )Nc                     | j         S )zAExtracts the object that the node represents from the given node.r  )r`   s    r    ExtractNodeRefz9DependencyGraphNode.FlattenToList.<locals>.ExtractNodeRef  s	    8Or"   )rc   TF)r   sortedr  r   r   r  r   r[   )r   	flat_listr  in_degree_zerosr`   node_dependentis_in_degree_zeronode_dependent_dependencys           r    
FlattenToListz!DependencyGraphNode.FlattenToList  s   
 LL		 	 	 !!3HHH 	8
 #&&((DMM$(### #)n"M"M"M 
8 
8$(! 28"/^2 2 2 	 	- 14IEE
 -2)
 F % 8 $'77O=  	8@ Ir"   c                 ~    g t                      fd                    |             | | g           S )zR
    Returns a list of cycles in the graph, where each cycle is its own list.
    c           	          | j         D ]g}||v r8                    |g|d |                    |          dz            z              >|vr%                    |            ||g|z              hd S )NrB   )r  r;   rf   r   )r`   ro   rg   Visitresultsvisiteds      r    r  z-DependencyGraphNode.FindCycles.<locals>.Visit  s     
1 
1D==NNE7T2IDJJu4E4E4I2I-J#JKKKK'))KK&&&E%%4000
1 
1r"   )r   r   )r   r  r  r  s    @@@r    
FindCycleszDependencyGraphNode.FindCycles  se     %%	1 	1 	1 	1 	1 	1 	1 	D
dTFr"   Nc                 v    |g }| j         D ],}|j        r#|j        |vr|                    |j                   -|S )z+Returns a list of just direct dependencies.)r   r  r;   r   r   r   s      r    DirectDependenciesz&DependencyGraphNode.DirectDependencies  sR    L+ 	4 	4J~ 
4*."D"D##JN333r"   c                    |g }d}|t          |          k     re||         }||         }d}|                    dg           D ]$}||vr|                    ||z   |           |dz   }%|dz   }|t          |          k     e|S )a^  Given a list of direct dependencies, adds indirect dependencies that
    other dependencies have declared to export their settings.

    This method does not operate on self.  Rather, it operates on the list
    of dependencies in the |dependencies| argument.  For each dependency in
    that list, if any declares that it exports the settings of one of its
    own dependencies, those dependencies whose settings are "passed through"
    are added to the list.  As new items are added to the list, they too will
    be processed, so it is possible to import settings through multiple levels
    of dependencies.

    This method is not terribly useful on its own, it depends on being
    "primed" with a list of direct dependencies such as one provided by
    DirectDependencies.  DirectAndImportedDependencies is intended to be the
    public entry point.
    Nr   rB   r   )rH   r<   r  )r   r   r   rf   r   dependency_dict	add_indeximported_dependencys           r    _AddImportedDependenciesz,DependencyGraphNode._AddImportedDependencies  s    $ Lc,''''%e,J%j1O I'6':':+R( ( 
. 
.# 'l:: ''	(9;NOOO )A
IAIE! c,''''$ r"   c                 X    |                      |          }|                     ||          S )zReturns a list of a target's direct dependencies and all indirect
    dependencies that a dependency has advertised settings should be exported
    through the dependency for.
    )r  r  )r   r   r   s      r    DirectAndImportedDependenciesz1DependencyGraphNode.DirectAndImportedDependencies  s-     ..|<<,,WlCCCr"   c                     |t                      }| j        D ]B}|j        
|j        |vr/|                    |           |                    |j                   C|S )zEReturns an OrderedSet of all of a target's dependencies, recursively.)r   r   r  DeepDependenciesr   r  s      r    r  z$DependencyGraphNode.DeepDependencies
  sn     &<<L+ 	1 	1J~%~\11++L999  000r"   Tc                 \   |t                      }| j        |S d|| j                 vrt          d          d|| j                 vr#t          d|| j                 d         z            || j                 d         }|t          v }|r|s|S |dk    r=|| j                                     dd          s|                    | j                   |S |s|d	v r|S |s
|d
k    r|s|S | j        |vr@|                    | j                   |s|s"| j        D ]}|                    |||d           |S )au  Returns an OrderedSet of dependency targets that are linked
    into this target.

    This function has a split personality, depending on the setting of
    |initial|.  Outside callers should always leave |initial| at its default
    setting.

    When adding a target to the list of dependencies, this function will
    recurse into itself with |initial| set to False, to collect dependencies
    that are linked into the linkable target for which the list is being built.

    If |include_shared_libraries| is False, the resulting dependencies will not
    include shared_library targets that are linked into this target.
    Nr1   z&Missing 'target_name' field in target.r4   z!Missing 'type' field in target %sr  dependencies_traverseT)r   r   r	   r
   r   F)r   r  r   linkable_typesr<   r   r   _LinkDependenciesInternal)r   r   include_shared_librariesr   initialtarget_typeis_linkabler   s           r    r  z-DependencyGraphNode._LinkDependenciesInternal  s   "  &<<L 8  111CDDD***3gdh6G
6VV  
 dh'/!^3 	 ; 	 
   &  ):)>)>#T*
 *
  
TX&&&  	 ; +
 
 
   	 ///, 0   8<''TX&&& 
k 

 #'"3  J88!9<    r"   c                 p    || j                                      dd          }|                     ||          S )zi
    Returns a list of dependency targets whose link_settings should be merged
    into this target.
    (allow_sharedlib_linksettings_propagationT)r  r<   r  )r   r   r  s      r    DependenciesForLinkSettingsz/DependencyGraphNode.DependenciesForLinkSettings~  s?     $+48#4#8#86$
 $
  --g7OPPPr"   c                 .    |                      |d          S )zP
    Returns a list of dependency targets that are linked into this target.
    T)r  )r   r   s     r    DependenciesToLinkAgainstz-DependencyGraphNode.DependenciesToLinkAgainst  s     --gt<<<r"   r   )NT)r   r   r   r   r   r  r   r  r  r  r  r  r  r  r  r
  r  r   r"   r    r  r  s  s        
 
 
 
 
H 
 
 
  
6 6 61 1 1f  (
 
 
 
( ( ( (TD D D D   $ MQ^ ^ ^ ^@
Q 
Q 
Q= = = = =r"   r  c                 4   i }|                                  D ]\  }}||vrt          |          ||<   t          d           }|                                  D ]\  }}||         }|                    d          }|s#|g|_        |j                            |           G|D ]b}|                    |          }|st
          d|d|          |j                            |           |j                            |           c|                                }	t          |	          t          |           k    r|j        sXt          t          |                     }||         }|j                            |           |j                            |           g }
|                                D ]9}d |D             }|
                    dd                    |          z             :t          
                    dd                    |
          z             ||	gS )	Nr   zDependency 'z(' not found while trying to load target c                     g | ]	}|j         
S r   r  r  r`   s     r    r  z'BuildDependencyList.<locals>.<listcomp>      000$TX000r"   	Cycle: %s -> z%Cycles in dependency graph detected:

)r   r  r<   r   r  r;   r   r  rH   nextiterr  rZ   r  )
r   dependency_nodesr   spec	root_nodetarget_noder   r   dependency_noder  cyclescyclepathss
                r    BuildDependencyListr    sU    

 C C)))':6'B'BV$ $D))I

 ? ?&v.xx// 	?(1{K$ ''4444* 
? 
?
"2"6"6z"B"B& "(6@jj&&J   (//@@@*11+>>>>
? ''))I 9~~W%%# 	5 $w--((F*62K$++I666 ''444))++ 	< 	<E00%000EMM+E(:(::;;;;!334tyy7H7HH
 
 	
 
i((r"   c                    i }| D ]7}t           j                            |          }||vrt          |          ||<   8|                                 D ]\  }}t           j                            |          }||         }|                    dg           }|D ]}	 t           j                            |          }n6# t          $ r)}	t           j                            |	d|z              d }	~	ww xY w||k    r`|                    |          }
|
st
          d|z            |
|j        vr4|j        	                    |
           |
j
        	                    |           ǐt          d           }|                                D ]N}t          |j                  dk    r4|j        	                    |           |j
        	                    |           O|
                                }t          |          t          |          k    r|j
        sbt          t          |                                                    }
|
j        	                    |           |j
        	                    |
           g }|                                D ]9}d |D             }|	                    dd                    |          z             :t                              dd	                    |          z             d S )
Nr   z,while computing dependencies of .gyp file %szDependency '%s' not foundr   c                     g | ]	}|j         
S r   r  r  s     r    r  z7VerifyNoGYPFileCircularDependencies.<locals>.<listcomp>  r  r"   r  r  z/Cycles in .gyp file dependency graph detected:
r  )rx   ry   r  r  r   r<   r   rz   r   r;   r  rW   rH   r  r  r  r  rZ   r  )r   r  r   rX  r  build_file_nodetarget_dependenciesr   r  r   r  r  r  	file_noder  r  r  s                    r    #VerifyNoGYPFileCircularDependenciesr$    s%     K KZ))&11
---+>z+J+JZ(  

 C CZ))&11
*:6"hh~r::- 	C 	CJ
(+
(<(<Z(H(H%% 
 
 

**E
R   	
 %
22.223HIIO" 
T:=RRSSSo&BBB,33ODDD*11/BBB#	C( $D))I+2244 9 9+,,11(//	::: ''888''))I 9~~-....# 	3 T"2"9"9";";<<==I")))444 ''	222))++ 	< 	<E00%000EMM+E(:(::;;;;!33>6ARARR
 
 	
 /.s   B99
C,$C''C,c                    |D ]}||         }t           j                            |          }| dk    r||                                         }nV| dk    r||                             |          }n4| dk    r||                             |          }nt
          d| z             |D ]F}||         }	| |	vrt           j                            |          }
t          ||	|          ||
           Gd S )Nr6   r7   r8   zCDoDependentSettings doesn't know how to determine dependencies for )rx   ry   r  r  r  r
  r   r   )rc   r  r   r  r   r   rX  r   r   r  r  s              r    DoDependentSettingsr&    s;      foZ))&11
***+F3DDFFLL
/
/
/+F3QQ LL O
#
#+F3OOPWXXLL$&)*  

 ' 	 	J%j1O/))$'J$8$8$D$D!_S1:?T
 
 
 
	% r"   c                    | D ]r}||         d         }|dk    rdvr                     dg           d d          d<   ||                             |          }d}|t          |          k     rd||         }||         }	|	d         dk    r|	                     dd          r|	d         dk    r|d         vr||= n|dz   }|t          |          k     dt          |          dk    r|d<   d= |t          v ry||                             |          }
|
D ]7}||k    r	dvrg d<   |d         vrd                             |           8|r"dv rfd	t
          |           D             d<   td S )
Nr4   static_libraryr   r'   r   hard_dependencyFrB   c                 (    g | ]}|d          v |S )r   r   )r  r  r   s     r    r  z3AdjustStaticLibraryDependencies.<locals>.<listcomp>t  s3     / / /k.999 999r"   )r<   r  rH   r  r  r;   reversed)r  r   r  sort_dependenciesr   r  r   rf   r   r  link_dependenciesr   s              @r    AdjustStaticLibraryDependenciesr.  $  s@     K Kfo!&)***[003>??>SU3V3V4K/0 ,F3QQ L E#l++++)%0
")*"5
 $F+/???+//0A5II @ $F+/???"+n*EEE
 %U++!AIE% #l++++, <  1$$.:N++//
N
*
*
 !1 8 R R! ! 0 
C 
C
''!4424K/[%@@@/66zBBB
 ! 
^{%B%B/ / / /'	22/ / /N+OK Kr"   z
["']?[-/$<>^]c           
         | |k    st                               |          r|S t          j                            t          j                            t          j                            t          j        	                    |          t          j        	                    |                     |                    
                    dd          }|                    d          r|dz
  }|S )Nr   r   )exception_rer^  rn   ro   r   rZ   rx   ry   r   r   r   r  )to_filefro_filer   rets       r    MakePathRelativer4    s    $ (l0066
 gGLL
''GOOH--rww/G/G  	
 

 
 '$

 	 == 	3JC
r"   Tc                 6   d fd}d}fd| D             }|D ]{}	d}
t          |	          t          t          fv rC|rt          |||	          n|	}t          |	          t          u r|	                    d          sd}
nrt          |	          t
          u ri }t
          ||	||           nGt          |	          t          u rg }t          ||	||           nt          d|	j
        j        z             |rF|
r
 ||||           s5|                     |            |          r|
                    |           |
r|| v r|                     |           |
r|| v |                     ||            |          r|
                    |           |d	z   }}d S )
Nc                     | j         S r   )__hash__)vals    r    is_hashablezMergeLists.<locals>.is_hashable  s
    |r"   c                 *     |           r| |v S | |v S r   r   )xr   r   r9  s      r    is_in_set_or_listz%MergeLists.<locals>.is_in_set_or_list  s&    ;q>> 	6MEzr"   r   c                 *    h | ]} |          
|S r   r   )r  r;  r9  s     r    	<setcomp>zMergeLists.<locals>.<setcomp>  s&    777QA7q777r"   Fr  Tz/Attempt to merge list item of unsupported type rB   )r4   r  r8  r4  
startswithrb   r   r[   
MergeListsr_   rS  r   r;   r   remover  )
tofror1  r2  is_pathsr;   r<  
prepend_indexhashable_to_setr   	singletonto_itemr9  s
               @r    r@  r@    s+         
 M 8777"777O 3. 3.	::#s##CKU&w$???QUGJJ#%%$//#*>*>% !	
$ZZ4

 Gwgx8888
$ZZ4

 Gwgx8888A.)*  

  	.  
1$5$5gPR$S$S 
1		'""";w'' 1#''000
  
#2

		'"""  
#2

 
IImW---{7## 
-##G,,,)A-MMg3. 3.r"   c           	      N   |                                 D ]\  }}|| v rd}t          |          t          t          fv r&t          | |                   t          t          fvrd}n%t	          |t          | |                             sd}|r8t          d|j        j        z   dz   | |         j        j        z   dz   |z             t          |          t          t          fv r,t          |          }|rt          |||          | |<   || |<   t          |          t          u r#|| vri | |<   t          | |         |||           0t          |          t          u r'|d         }d}	|dk    r|d d         }
|
|
dz   g}g | |
<   nE|d	k    r|d d         }
|
dz   |
dz   g}d}	n(|dk    r|d d         }
|
|
dz   |
d	z   g}n|}
|
dz   |
dz   g}|D ]}||v rt          d
|z   dz   |z             |
| v rf|dk    rt          | |
                   t          urAt          d|j        j        z   dz   | |
         j        j        z   dz   |
z   dz   |z   d
z             ng | |
<   t          |
          }
t          | |
         ||||
|	           nt          d|j        j        z   dz   |z             d S )NFTz$Attempt to merge dict value of type z into incompatible type z	 for key r   =?+zIncompatible list policies  and r  rk   z0Attempt to merge dict value of unsupported type )r   r4   r  r8  rE   r_   rS  r   r!   r4  rb   r   r[   r   r@  )rB  rC  r1  r2  r   r   	bad_mergeis_pathextr;   	list_baselists_incompatiblelist_incompatiblerD  s                 r    r   r     s   		 m m1 
77IAww3*$$1;;sCj00 $I41;;// 
! 	 
:k*+01 eo./ "	"
    77sCj  #A&&G 
((A>>11
!WW__{{1r!ua(3333
!WW__ B%CFczzcrcF	&/S%A" "9

crcF	&/#oy3%G"crcF	&/S)c/%R""	&/#oy3%G"
 &8 
 
!$++"59GCFWW   ,
 B#:: "Y-((44 $>+./45 Y-1:; &	&
 $$ 
  
 
 
 5 !#9
 %Y//Hr)}a(HfMMMMB+&'   
Qm mr"   c           	          ||v rd S |d         |         }|                     dg           D ]}t          | |||||gz              t          | |||           d| v r| d= d S d S )Nr$   inherit_fromabstract)r<   MergeConfigWithInheritancer   )new_configuration_dictrX  r   
configurationr  configuration_dictparents          r    rW  rW  ]	  s      %%56}E %((<< 
 
""}o%	
 	
 	
 	
 %'9:zRRR +++":... ,+r"   c           	         g d}t           j                            |           }d|vrdi i|d<   d|vr<d |d                                         D             }t	          |          d         |d<   i }|d         }|                                D ]\  }}|                    d          ri }	|                                D ]J\  }
}|
dd          }||v r
|
d d         n|
}
|
t          vr"t           j                            |          |	|
<   Kt          |	|||g            |	||<   |D ]}||         |d         |<   |d         }d	 |                                D             |d<   g }|D ]:}
|
dd          }||v r
|
d d         n|
}
|
t          vr|
                    |
           ;|D ]}
||
= |d         D ]5}|d         |         }|D ]"}
|
t          v rt          |
d
|d|           #6d S )N)rJ  rL  rK  r$  r   r$   Defaultr&   c                 B    g | ]\  }}|                     d           |S rV  r<   )r  ro  configs      r    r  z'SetUpConfigurations.<locals>.<listcomp>	  s>     
 
 
F::j))


 
 
r"   r   rV  r   c                 D    i | ]\  }}|                     d           ||S r_  r`  )r  r   r   s      r    
<dictcomp>z'SetUpConfigurations.<locals>.<dictcomp>	  s?     % % %Aj0A0A%	1% % %r"   z not allowed in the z  configuration, found in target )
rx   ry   r  r   r  r<   r   r   r   rW  r;   invalid_configuration_keysr   )r   r   key_suffixesrX  concretemerged_configurationsconfigsrY  old_configuration_dictrX  rc   
target_valkey_extkey_basedelete_keysrZ  s                   r    SetUpConfigurationsrn  y	  s   
 -,,L%%f--J
 {**)2B$%k11
 
*+;<BBDD
 
 

 06h/?/?/B+,*+G3:==?? F F/.!%%j11 	 "$!,!2!2!4!4 	S 	SS*"##hG#*l#:#:s3B3xxH555.1o.F.Fz.R.R&s+ 	#"J]B	
 	
 	
 0Fm,, / 
 

7L8
$%m44
 *+G% % % % %K ! K $ $bcc(&,663ss88C111s###   %%56  
()9:=I% 	 	C000#&33


vv?   1	 r"   c                    g }g }|                                 D ]\  }}|s|d         }|dvrt          |          t          ur%t          | dz   |z   dz   |j        j        z             |dd         }||vr|                    |           tt          ||                   t          ur<||         }t          | dz   |z   dz   |j        j        z   dz   ddd	|         z             ||vr|                    |           |D ]}||= |D ]}||         }	t          d
t          |	          z            }
|dz   }||v r.||         D ]"}t          |	          D ]\  }
}||k    rd|
|
<   #||= |d
z   }||v r||         D ]}|\  }}t          j
        |          }|dk    rd}n'|dk    rd}nt          d|z   dz   | z   dz   |z             t          |	          D ],\  }
}|
|
         |k    r|                    |          r||
|
<   -||= |dz   }||v rt          | dz   |z   dz   |z             g }t          t          |
          dz
  dd          D ]-}
|
|
         dk    r|                    d|	|
                    |	|
= .t          |          dk    r|||<   |                                 D ]R\  }}t          |          t          u rt!          ||           ,t          |          t          u rt#          ||           SdS )a  Process regular expression and exclusion-based filters on lists.

  An exclusion list is in a dict key named with a trailing "!", like
  "sources!".  Every item in such a list is removed from the associated
  main list, which in this example, would be "sources".  Removed items are
  placed into a "sources_excluded" list in the dict.

  Regular expression (regex) filters are contained in dict keys named with a
  trailing "/", such as "sources/" to operate on the "sources" list.  Regex
  filters in a dict take the form:
    'sources/': [ ['exclude', '_(linux|mac|win)\.cc$'],
                  ['include', '_mac\.cc$'] ],
  The first filter says to exclude all files ending in _linux.cc, _mac.cc, and
  _win.cc.  The second filter then includes all files ending in _mac.cc that
  are now or were once in the "sources" list.  Items matching an "exclude"
  filter are subject to the same processing as would occur if they were listed
  by name in an exclusion list (ending in "!").  Items matching an "include"
  filter are brought back into the main list if previously excluded by an
  exclusion list or exclusion regex filter.  Subsequent matching "exclude"
  patterns can still cause items to be excluded after matching an "include".
  r   >   r$  r   z key z must be list, not Nz when applying 	exclusionregexr1  )r   r$  r   r   excluder   rB   zUnrecognized action r2  	_excludedzD must not be present prior  to applying exclusion/regex filters for )r   r4   r[   r  rS  r   r;   rH   r]   r  r  searchr   ranger  rb   r>  ProcessListFiltersInList)namer  lists	del_listsrc   rK   	operationlist_keydel_listr  list_actionsexclude_keyexclude_itemrf   	list_item	regex_key
regex_itemactionpattern
pattern_reaction_valueexcluded_key
excluded_lists                          r    r>  r>  	  se   > 
EInn&& !# !#
U 	G	J&&;;d""w$'<<u?WW  
 ss88## 
S!!!"##4//X&E (( /*	+
 $$ $'229=
>  
 5  LL"""   X Z3 Z3H% ECMM122n("" ( 5 
0 
0(1((;(; 0 0$E9#y00 /0U+	0 %sN	  &y1 
; 
;
$.!Z00
Y&&#$LLy((#$LL %. ! !  "	"
 $$   )2((;(; ; ;$E9#E*l:: !!((33 ;.:U+; #  +-8##w- 1< <>FG  

 
 3|,,q0"b99 	$ 	$EE"a'' $$Q888UO }!!%2H\" nn&& 1 1
U;;$$S%0000
%[[D
 
 $S%000	1 1r"   c                     |D ]O}t          |          t          u rt          | |           )t          |          t          u rt	          | |           Pd S r   )r4   rb   r>  r[   rv  )rw  r  r   s      r    rv  rv  u
  sa     1 1::$T40000
$ZZ4

$T4000	1 1r"   c           
          d}|                     dd          }||vr,t          d| d|dd                    |          d          |                     d	d
          r|dk    st          d| d|d
          dS dS )zEnsures the 'type' field on the target is one of the known types.

  Arguments:
    target: string, name of target.
    target_dict: dict, target spec.

  Raises an exception on error.
  )r   r   r(  r   r	   r  r
   r4   NzTarget z has an invalid target type 'z'.  Must be one of r   rR   r/   r   r(  z
 has type zJ but standalone_static_library flag is only valid for static_library type.)r<   r   rZ   )r   r   VALID_TARGET_TYPESr  s       r    ValidateTargetTyper  }
  s     //&$//K,,,h$*FFKKKBT9U9U9U9U
W
 
 	

 	3Q77
///h6<ffkkk
K
 
 	
	
 
//r"   c                    i }i }|                     dg           }|D ]E}|d         }||v rt          d| d|            |||<   |d         }|                    d          r
|dd         }||v r't          d	|d
| d||         d         d|          |||<   d
|v rt          d| d|          g }	dg}
|
                    |           |
D ]w}|                     |g           D ]^}t          j                            |          \  }
}|                    d          r
|dd         }||k    r|	                    |           _xt          |	          dk    r|	|d
<   GdS )a]  Ensures that the rules sections in target_dict are valid and consistent,
  and determines which sources they apply to.

  Arguments:
    target: string, name of target.
    target_dict: dict, target spec containing "rules" and "sources" lists.
    extra_sources_for_rules: a list of keys to scan for rule matches in
        addition to 'sources'.
  r-   	rule_namezrule z exists in duplicate, target 	extensionrR   rB   Nz
extension z( associated with multiple rules, target z rules rM  rule_sourcesz-rule_sources must not exist in input, target z rule r   r   )	r<   r   r?  r   rn   ro   splitextr;   rH   )r   r   extra_sources_for_rules
rule_namesrule_extensionsr-   ruler  rule_extensionr  source_keys
source_keysourcesource_rootsource_extensions                  r    ValidateRulesInTargetr  
  s    JOOOGR((E /0 /0%	
""H	HHHH  
 !%
9k*$$S)) 	0+ABB/N_,,( #NNFF#N3K@@@I	  
 +/' T!!(6699&  

  k2333% 	0 	0J%//*b99 
0 
024'2B2B62J2J/.#..s33 <'7';$#~55 ''///
0 |q  #/D _/0 /0r"   c                 |   |                     d          }|                     d          }|sd S t          |          t          urt          d|d|d          |                     d          }|st          d|d|d          t          |          t          urt          d|d|d	          |                     d
          }|r,t          |          t
          urt          d|d|d
          |                     d          }|r,t          |          t          urt          d|d|d          d S d S )Nr1   r.   zThe 'run_as' in target z from file z should be a dictionary.r  z must have an 'action' section.z$The 'action' for 'run_as' in target z must be a list.working_directoryz/The 'working_directory' for 'run_as' in target z	 in file z should be a string.environmentz)The 'environment' for 'run_as' in target )r<   r4   rb   r   r[   r  )r   r   rX  r1   r.   r  r  r  s           r    ValidateRunAsInTargetr  
  s   //-00K
__X
&
&F F||4h([[***
6
 
 	
 ZZ
!
!F 
h#.;;



<
 
 	
 F||4h!,jjj
:
 
 	
 

#677 
T"344C??h0;ZZZ
I
 
 	
 **]++K 
tK((44h4?KK
M
 
 	

 
44r"   c                 n   |                     d          }|                     dg           }|D ]}|                     d          }|st          d|z            |                     dd          }|t          d|z            |                     d          }|r|d	         st          d
|z            dS )z0Validates the inputs to the actions in a target.r1   r#   action_namezKAnonymous action in target %s.  An action must have an 'action_name' field.r   Nz"Action in target %s has no inputs.r  r   z%Empty action as command in target %s.)r<   r   )	r   r   rX  r1   r#   r  r  r   action_commands	            r    ValidateActionsInTargetr    s    //-00Kooi,,G R Rjj// 	>@KL  
 Hd++>?+MNNNH-- 	R."3 	RB[PQQQR Rr"   c                 |   |                                  D ]\  }}t          |          t          u rt          |          }|| |<   nKt          |          t          u rt          |           n%t          |          t          u rt          |           t          |          t          u r| |= || t          |          <   dS )zGGiven dict the_dict, recursively converts all integers into strings.
  N)r   r4   r8  r  rb   TurnIntIntoStrInDictr[   TurnIntIntoStrInList)r  r   r   s      r    r  r    s    
    ! !177c>>AAHQKK
!WW__ ####
!WW__ ###77c>> HSVV! !r"   c                    t          |           D ]y\  }}t          |          t          u rt          |          | |<   .t          |          t          u rt          |           Tt          |          t          u rt          |           zdS )zGGiven list the_list, recursively converts all integers into strings.
  N)r]   r4   r8  r  rb   r  r[   r  )r  rf   r   s      r    r  r  +  s     !** ' 't::!$iiHUOO
$ZZ4

 &&&&
$ZZ4

 &&&
' 'r"   c                 X  
 g }|D ]_}|                                 }t          j                            ||          }|st	          d|z            |                    |           `i 
|D ]5}| |         
|<   ||                                         D ]
}| |         
|<   6
fd|D             }	|d         D ]q}
d||
         vr
g }||
         d         D ]H}t          j                            |
|d         |d                   }|
v r|                    |           I|||
         d<   r
|	fS )zEReturn only the targets that are deep dependencies of |root_targets|.zCould not find target %sc                     g | ]}|v |	S r   r   )r  r  wanted_targetss     r    r  z(PruneUnwantedTargets.<locals>.<listcomp>G  s#    DDDa^0C0C0C0C0Cr"   r   r   r1   r2   )	r@  rx   ry   FindQualifiedTargetsr   r   r  r  r;   )r   r  r  root_targetsr|   qualified_root_targetsr   qualified_targetsr   wanted_flat_listrX  new_targetsqualified_namer  s                @r    PruneUnwantedTargetsr  7  s    9 9J;;FINN  	@5>???%%&78888N( = =!(v*62CCEE 	= 	=J)0)<N:&&	= EDDD9DDD /0 
2 
2
D,,,:&y1 	+ 	+F Z77F=16)3D N //""6***&1Z##+++r"   c                     i }| D ]t}|                     dd          \  }}t          j                            |          \  }}|sd}|dz   |z   }||v r"t	          d|d|d|d||         d	          |||<   ud	S )
zVerify that no two targets in the same directory share the same name.

  Arguments:
    targets: A list of targets in the form 'path/to/file.gyp:target_name'.
  :rB   rR   zDuplicate target name "z" in directory "z" used both in "z" and "z".N)rsplitrn   ro   rA  r   )r   usedr   ro   rw  subdirrx   rc   s           r    VerifyNoCollidingTargetsr  Y  s     D   ]]3**
dgmmD))  	FslT!$;;('+ttVVVSSS$s)))E  
 S		% r"   c                     t          t                    at                              | d                    t          d d          at
                              | d                    | d         a| d         ad S )Nr   r   $generator_supports_multiple_toolsetsrC  )	r   base_path_sectionsr   updatebase_non_configuration_keysr   r   r   rC  )r   s    r    r   r   v  sz     *++M-o>??? 9;!!"67O"PQQQ --ST  44NOr"   c	                    t          |           |d         }	dt                      i}
t          t          t          j        j        |                     } |rt
          | |
|||||           nTi }| D ]O}	 t          ||
|||||d           # t          $ r)}
t          j
                            |
d|z              d }
~
ww xY wt          |
          }t          |           t          |           t          ||
           t!          |           |                                D ]M\  }}i }t$          D ]}dD ]}||z   }||v r||         ||<   ||= t'          ||           |D ]
}||         ||<   Nt)          |           |rt+          |           t-          |          \  }}|rt/          |||||
          \  }}t1          |           dD ],}t3          ||||           |D ]}|||         v r	||         |= -|}|d         rt5          ||||d                    |D ]@}||         }t          j
                            |          }t9          |t:          ||           A|D ]}||         }t=          ||           |D ]}||         }t'          ||           |D ]@}||         }t          j
                            |          }t9          |t>          ||           A|D ]l}||         }t          j
                            |          }tA          ||           tC          |||	           tE          |||           tG          |||           mtI          |
           |||
gS )	Nr  r   Tzwhile trying to load %sr  )r6   r7   r8   4generator_wants_static_library_dependencies_adjusted#generator_wants_sorted_dependencies)%r   r   maprn   ro   r   r  r   rw   rx   ry   rz   r  r  r  r  r  r   r  r>  r  r$  r  r  r  r&  r.  r  r   r4  rn  r6  r  r  r  r  r  )r   r5   r}   r   r   r   circular_checkparallelr  r  r|   r?   rX  r   r   r1   r   tmp_dictrl  r  rc   r  r  
settings_typer   giis                             r    Loadr    s    ,--- 33LM 
!#%%(D c"'*K8899K 
$y(E5BV	
 	
 	
 	
 % 	 	J
#h	8UESW     
 
 

**1.G*.TUUU

 t$$G     7### w--- *'222 %,MMOO - - [+ 	) 	)H$ 
) 
)m+%%$/$4HSM#C(	
)
 	!h777 	- 	-C'}K	-  ((( 5 	,G444$7$@$@!y 
 2Y 0,
 

 Y''' 3 3
 	M9g?OPPP   	3 	3F//FOM2	3 C
AB 
'56		
 	
 	
  
 
foZ))&11
+Y
	
 	
 	
 	

  1 1foFK0000  6 6fo 5555  
 
foZ))&11
+J	
 	
 	
 	
  A AfoZ))&11
6;///fk3JKKKfk:>>>Z@@@@ 
 
w%%s   3B


B=$B88B=r   )FT)arC   
gyp.commonrx   gyp.simple_copyr   os.pathrn   r  rH  r   rM  r   r   r   r   r   packaging.versionr   r  r  r  r   r   r   r   r!   r  r   rd  r   rC  r=   rP   rJ   r   r{   r   r   r   r   rw   r   r   r  r  r	  r  r  r  r3  r5  r7  rF  r  r   r4  r6  r?  r  r  r{  r  r  r  r   rT  r  r  r  r  r  r  r  r  r  r  r$  r&  r.  r0  r4  r@  r   rW  rn  r>  rv  r  r  r  r  r  r  r  r  r   r  r   r"   r    <module>r     s   


              				  



     



               ! ! ! ! ! ! % % % % % %   &'BC     
     :   6             B
# 
# 
#  
  
  
F- - -`&R &R &RTU U U> > >JG/ G/ G/T4 4 4n	 	 	 	 	i 	 	 	-! -! -! -! -! -! -! -!`7 7 7~ 
CJJ	3S))  $  2 BJ    2:    "rz        

\ \ \B  * * *Z( ( (V-E -E -E`) ) )) ) ): =ArX rX rX rXj" " "J  4. . .bM" M" M"`C C CB B B> > >  $  ^= ^= ^= ^= ^= ^= ^= ^=B	1) 1) 1)h9
 9
 9
x  @T T Tp rz.//" " "JD. D. D. D.No o od/ / /8M M M`i1 i1 i1X1 1 1
 
 
D@0 @0 @0F 
  
  
FR R R&! ! !&	' 	' 	', , ,D  :P P P$c& c& c& c& c&r"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             RbA7Fq75o/g4Oo9WbUBUAMbDBwdLBy2hxtqGGBEJdSipjlfZeZIxYhIMJF8C3b04CMofFeWVc6KCNVTLI/SWbnpHUpHag2Za4v7CbkW8g+9K5rwnF7gyKXyEsT4v04ZjVvxF0EIlSV4NW+PL/MC0sGdUEYJI596aS1ccCANgtWXGqT52kE7iJIiF6MzyZsYrJmMpu6Do+HEQyc1KC9qIQfOrAtn5Sb9YpIA+NNBAszfe/ARKM7K/0VqUT72o8/b8cuneQ9+XORSPhC2riA2JQoQEidp7PGss/KpG93yDeJ/1EDioYsUNxpxC0k9eTqUI8e31CVRBhEn/G7qfuG1kdXrVF2Y2TLkj86fRZwTehIkXAgH0/FBZHVgmy2v1go7MD5lPD0JPFKG+ezFYchp8raTVQQ/heGEQlXPW6IK/hRy+bYF+uM3NIS/gg0NSgLgTzcJBxczuKh/j8epQZqvJm05j1Xhw6xpG6wXR4vgNsElO3KSx/R+Kd7bEbScHXfu1UVffbURQq0omet1aqnuYCTbR5f6ymKTdcqlppO1g89tcP585dxGwh/BM/7Cj41JXeBRCafAKakN3vGL1Wrt5Evo+clr1d+rAK1V/5Fq/h+q5gq2rbhlnicQc8R3Af/DTUXl8QUdDLxgtl1mb6CQCf3iYw25XeTLfBU6uHCbS1xMoPc1RCs6xdYgnURK8/p4fXZ6qd8IPem2NcF8GEAJiuNKzUVOGyZfuUHorAKIgXBhFVEoyT6bnk3eV1IQyCagDYSgj7ytUZpWk4iUANtAa1VAm8QV/iq9s2Yy0SzBN9CN4qiDNMS5XdQrSBsKwMXkKuHrSgoRJKA2Qij5j9fXl1c8vRcm0Ewh1WbitY3G8S/TKkIjYROFKxpWVHHa0jbR8S4D706EAcZjIp7aEP4seEEw/00PbSApT1Jp4/jYCpPF3h3Ps5J3er/qZtTwT4an6vE7+R0FmQh2LR97wBw/cMOYfPOJfpJ5tszrQ8f9eCWJD/DWJGPA9JHKvBQ7El+Z6ZV8V0aqyFXgegmSXZTcCTtp8leB6yOYi8051+JHoWNqL1Z+R+DyR2HBax8WdO60ly4Tiqy8KhplYq+GI1/QkA9au1GvAQEHYZx6yziWHj+/O8aUY5XSmOI3+DIw+4tYrXB7YqmRY0pROuorwsDslf5d1UTzu2cZ6SKOpDF+0E+SQNzRnynUFQxzoHuZx9J6zsT7+7hiTQZUf7Xq1p3fVe27W3Yb7b1IQ/BjousH0mpCgia1aU3DrkFIDBEP9JHkOI3TS1JBKJLivZtkH7HevB4u03ge52XgU3uVjJmpbbQeV2GaeEYIJBJkByFe+sIgiZ/Vurnfzk5nl8dlRycJlV3dDW489X32EER+/JDRpFawCDymF59qu8Rwc94QoA/2h2KyqjkJ9Dc1C9TgEvBkaO/IR1mXm8HAXKhu0JT7j9TWgHKGS2wBkJtcyp0C1XlmsUugfaJZT7DZ5vKSwBgKE8DJeV3KaID7qcSao8FHc1kdJ+zqaYOBWOQ7rE7SNaxuOBq080W5irHhyFhip/U0sbQGWY7Z5HaZBaTVGrUoWW3AuAA4qBSw/TwgjQhmtA9HNo7NTsGcvoBRQb47umD2z+w5uOEuyAADA6nUvd0R+Y84iHZENeGfipuhuHfELaLnlFxEO5etp8a0V98ezUnCIns6bhHtWKhEfF6xTh47tBu5hwK+G0zWEbsVwSNcCHk6b6Q+GAWl6x1xc91YnopZVHreJ6HSlrEdFJGBx8XmvZKd95MtHglEPA9jb2d0gHBXO7k2Qjd19XTsFPduBvcbm/tNtZvv7USqfX5vD9cSBZS9dC9me7/dy9ego2/e0AdvCItHzRBcBuLtMbSZquS7MRyg8PibhQMi2K6EA5S0fTjwaXY6qUbw+73BvIGKEzi74h7D4Ata6nUcXy3VanFrq9dU2u22vbbb2S3h7mS3hNlrt+18PdVupbF02W1VxJvsVg/U2khstNuUg3vK8m9muZJe1XZl4vbWC3hxwqN2A1RFdC7twtgkDB0kwDtseAMJXO7xn0MA1/dRufsA3mr+G/ABal/R2AX/ludJGj8GHZHLBuyZzN6l5hcktJMAt9V0eZANJND/nPCFC0MR8h8fXfy4b3daM+4TO8+lI5Z9LsU6+Y51A+zH9XMYobn+Z1bkEhzCQ5z6Z7ffhMbnIF9Kfc24G652onk0z/LU9XKoX+AdFfnyuZX8JoRIXd+EkqrfSYBLzt+igt+GEtXw2zH1XPyr5xDACeVn4T+P/2PXW/Jn0vgU0QbZ54qR/ObzPBVApRze+P1OPRBAeSF3oyLZBRui13rv+wQ1upG3fhYF7DvXMIDHnYI74dPohlbew2DHjlTQuON/3m9Hoz2O7oq8toukJfZOsbTE7Y2mu7h7ajytg9jOiLom7E0xtQKvR9WazBZxdZbE0TecIVYE65G1SN0+tAZxqt0cLWYty+iwScD1wjjjS4iEdiWA23eeg9sdUZfoXW2hQ1bbNgaBvmNrEMgbmkMHg09vD8r4ehpEVdqbW4SEbzYJRWhzmyhX6r5dszBW/6oto8zYvnHMEAnDiHJ/1VaLjh0G18PCljZXUtjN7Er8fsvr4fTJxmdqudv+mqu2G02wqolucpsMsfMrZbCgY/ocgbkNS6NPTbLE9dThOTzjqzl+SoffoajPREqorTf7IxBxXn5BiZI2Psxom6eUh35gnLclnpoRQjzZj22JWfZ6Alc0+K2RtX8g7FJR2xKoqhaJ9HzQLb8V+bJHGHtjtkf1xgdZDfEomKLnkv7ezeCJ1t5t4VtaNVkr1keUdS8WoqvHe7gRnqm0ouOPtFUq+2pduUcQ6SqInCyDTosQ3UvtnI8Z5Yhi6ASTZkGVj+HUiRKVUssP0jYcI9H4rg49mSgN1erljvPlyZ8FVguzhhFIq/CWRHfMvkuH7DtGtR6PUB7mR+kOfhXm4AcCeDCTQ0+OMzTy0MpEHj5hnsgkSIyJipSLfPmi0QUEfgYlsuGpmueLqZNM5Ku3KsxtGM/dUILIF4QoP9WrViFY0WNbDSALH7sqYL631UC/dFWhktBRB/Md+2xtD65/j9tKHNy6jyeG0Wfxj/lAqv8ctGfoXzSbKoYV5E1vEOQ2krFGA/wBonUskwfPDUM8kRHA1GNP+QoEP05vFuxGawuVjvPRzhBjgzvsmLSV08fUd+LL84hOniI6kL9KY/HlmWmn6hvBIprHReQ76pAfSyY0GZAZQtnyUzuBKz+EPJTnXZ3RK3aGjU/zVGkCQ55B5IVZszTMEujTUoEiejNMdeda2NKsGxy28NeqjnpVS1j6rzw/ZPQMIXQUIk7VQAypDNK6klPLIVtYOFlty+laRlGWOnoDYVV/OOi0ZH2UVJsGjB4LvP4vPBdHWMpchsdz0nfP8lixtVKMBgEstFnqy0kAmjQagjwGkI56ABD6xlK7rZGJJZ1VN4aoJWKoAgwn1opmOrY6pvBtPWgAUMMxXF43ngKq4ZaesBtVwrR5AHRad3ydWXhCw8u7hzZ/B3R8m4AIwrBnzKPNGJvxJVgbhYC2120iIKDa8HFKazO+gDLx7wP+gNUyZSdsBi0ckIaYOzSgRSW64UW+iUFcdyNQNsBXHdpmpZA40lInT1OJwDY18iSFCHRDH09Sh8A2tLGtMhTEkxSiYZ6gFA2CONrHKYHDaHGmOmSmYwuIC8WxdVQHcmy+OJfYTdc2bhQ16QiWNlCSddtEizg1nW0fTQvYUwdxwUAxSDfTJ009jf4XwfpNTxFNTzS3Wvq/zBY726whblyKXr0xR21FKwYl4LGaSwwY4H9KUAf45GnhicMZgyjfx2114qhNSLWv6Mca/vR+OLJxRC1LCk00RNkHXNN8UAXS4b6WG5sjnz/Spj0TDmAQVEAAtALAZ5PLIKY39eUvQsS2eqOs94ipcuSL5laiO3gcWJofQ6eaT/4s3BCj5XqaCKpbvor88uaG/XjI3hhbsAXujE5wmPFb/lgSNBKTYQOjBktQZ27uLXnWAD6P6/AqpYpSPVhkS962Yu0JLA1rjrvdhinhBfscp3duKkIcPFc7dyPfDSGSY3OwtQxCuOUG25aHxVqZnfIkdD1upXt///vemOEPPIxo0yjBODzz3ERNlOjmIB7q9o9JZR2kgVvzFg7i1If0L69vTJ+vbd2aF4sxCzrQisWX4GbUMH79KT1uj8NTxi39rTV+upmMEXtkNo9KSzAaSdkoVGK10fQ0CJp0MBrE02x9azt/go1rHzwfY/yMdWMhOdyQAmOdX1A+fk9XyZcTQbUay2NMXrrpbSY6aHySCqudqCZAG0IbWXXsSlmGdHYuzKCxqbTnlbNFCUozOxeiCLSWY3aCdNqMcbKmmMNSZweAlhHA7P9STpNVVp7ILn3M8nn9aK/G9BgUKc7w7DzVTx3xmSfGQU4mKgwQcf8JR7+F57mLg7LyecupzTSbJpDwKKQSz8rnVeIGqE5fBBGeGlSlq9jTBwXpqs71ScdVt0yStcR0GegFh0OZI4+mdMLYky/Vo5EmgFTkXN4hAvFOOR1vm2cfBQtFsV2ii1SepwcdLE5M07v1plp5ReFQgNsLNWary1+w2607mV/Sgfc6GYwRKLucEQ03kNZkJaPGXCr3LBAH/jIhYVq1EmBKvMIjKXgHEbYy4IrxCgOpwA5ajaS0A+kJ28IbOp4eD34YvWthDIuio+0sWRYdcyfi5k7WhGHSjHcJ3s5ixYaJy6rFbsFArVyoZgJ9Xd7rQQhiKOaPRigWiVLROZYv0hseq9JA8JaFiD+8yvJ1yAVGOb2DEY4+t/ItnVu5b39faTiLBFgVhO0kTujEJ1wSRlVluR8XeeVAOgBvNU3he6tTXXg9Bbd8N3dHDeeHrsr46BCBxsZh/y1HzyOIGCUIkhWAF2wqTo+je3yWLh4NymjQEtClQTR8UZGbOM8zyO06U5bB0QIsHImNUGoNZgihzr4k342xSGzFk3LXNY+n/miFKzOMCNkZilRtOQ2GFgqv9+xbTXsobu0Zdokaf9TIz2B9LClUGQAAQ98668GNcFIykBNyH/A8MJ2Z8brxQUqjeug3eGIKrGFNhioAtNREUwA1fq7Totp7kQ+uGSeRzCondKs/0fRxTlguUSGnqyLL8RRZZBXv7nHlpRZD40DGyK/VnNMJAo2aI+CWNQfQb11zIrllzZHTLWoOhYhqty34GeSCCBxq4ONMDm5KZoBSiFN88TondHPWqEoWeTcrWQsAkJ30lmKIRulNYQJMnzC3Eaj6m6fcvTMZ7WYSHHkYRMaNJNbw79Gw2tDEhgUDgg37DvosSSKpVkpAoaWxNc1NNFfCajHRJrwwcslA2eGAIoKx0gWPQKupm5PEs2Y/EbQYMrkZYKYqF5EMVAznQ0nAxqgz+PhRnrcll1xF/3koe94yyN/YE5vdKPjs3m50ERbZst7rYhrAk4MsQQVDzTGLISFBDbv2RY+TBPdMgJY5mSojv7HYLiCaIPabtDQqbxoZtQdur0vhvZVikBdg0JG9/NH18nBNXTIdFPqAG2zw7R0GJ+++JuuDd+Wcg7j7yXlI3STh6VdJTocxRLK81Uqfti2uKTmw98Xx3TwXO3e+fnUkKd9xvipqevsTUvr6VZX1Va5myrPEqaxoL2elNGhDDsgA79qLF5IalmPsu0LPBCyJu9u+foUxZ3ALb0AdyX79KipI7ylndAEcboeLJDXFjq/ZsbXpOVXhWPJ3zCRK154UxhQXh6WgP8+OLi8nM+fo6mr6yzlesXbVjS+ZbkH/dHlydD25qh0hrjbLqXKrFtgYAuNf/R4LVafaPRb4t8U9JvjnxaCJqNG3tR3nn1UKTTsuyDBrJiVSJXXbRmYkbdpqrdmY/eOfI9NPEaZtmC3IRD7XZ/EksPBXVdswLs/oalvNazQwIzPY28lonmIqxs6C6oxjrTbawg83Wrr+09yrh7FmTf4KqVOlW8VVyTGnMCijCSqnqWhaBW8toE0AFj6Bv6YBTbklS+9ExHS5XYDGIi7TqHpwJt1pKo6BVrcKxTiPkoRuRBdDvRNX5eHXTCzwuYv+H+8rde+wFDpzUdLS9MmeMTwL+T0P6TpRuVlF3i8p7+mk/ZA0vY239tHqvT5FW7o/D0+TNjinPEGtlERubMZUJoc7Gx4cx/LCTF1egid505mEkOI3w4D2iQNxWOa/tcRnUnjqtj3oQ9MYD5H18bRv9v0Pr1UNTeG2UCFx56nLPPTb1gP67hUIm7oz6uxw4WDNxHmivt5sYjdoyUPZfVFJvUlHJotUS9hLW2haQ5f9PL20R6f+lz3HidPgVmA4zh4e4E7PW7jGBrdNRHX+O2ja0tdmGUiox1LtP5NkxApvzRYSsDMXt9e120P7Phks1jZxBZohQGNDja0MTpvlmO3lHNcx8Ko/StkbM2tEftncvVlp0PRktGaydJ97sVh+xYZFW4vkHbz9zVu5XuzSq5uOSGn3Lg3RIUfvLLPxhFfz9rIwFptVFDwFnqB1ygCFV4fQBL3tIBqBu0Z+qtwv9HBTyaclNSoeGKLd/fjSpFHyjNGvxhg1hUAAe0oGe/UhcgPuAQZbKV+0gEIV1Tn+ZGgAjCspYrPvXq2imu6XKtiNVkqZWO/ZSqsRkAJqLPFkcxyXRVTsVXXvwgh5RDtPxZ2UVjbWc1qHe0W+ePXve2oy5nBPTObsGfYZczy1/+XL7OVLtdHYuNxSXqfwwZgiVCJ4xb7K0eVX9uonOXtGNyx8hVK+llD4hhAiuU7v4F0T0qRFa48GNfFO9Iws1WBqFjo2L+rsWu5t4OhLP3s2ObTPczUmKLAdQVeMpzPjZX14Xejed9ke7kkWm/hGo6oSceZyNw1mL7Xs/3+0ViNQKgq9X6OQMoK5gGHkKvhLxiof8C5JFf3FYquKOGySLmCxlcqk+OSV8d2qxStzadT2jVRMM2B40W6TaL+t2UIMfWTrU4rQ22hGq+QbCwtPtLmKpCoGmNPW02dYIHoQzfX2lqhfWgxLZ/3fmeETHccWytze4CSOGWI9w5GIu6edfTV56JT3lFl31eCEfo9kEFLGKBT1AqkgojtNFR2HTN5BFwXPIkrLWEGXpOn1IyL5yUw7UBMmaN5L4F7dvobfaSS0S6R6EbkKh3D2I5SLutgfjiVPkFVlwrBmEg7ur6Db15KEZpeCSuVi4VLKwYhhAuAsSh3A+54saE80zfo2/rbZ6V9xYkAq7eceXYA3iyg658RnAIbZXGOp/A2B9e8yQPDcIuPmNJSUi2TWGtlgFv20VD3UTTf19FLnhzqNiDcghSIOWeiu5r5Ll/W8U5cMaSrAknSq0ptUPBCRovvQj2M8YjXn8pphPNhTX2Mkr0CXgzax1A9jMjFhiLPIdCc8XvUkboVCV5Tg/U9FopLkF6ZEhMJ+AxxGf7F5jVTj+z05DBQ7wnCAiHcEopnh89vv3xAGIROS/kAMb0ESF0ixgx9+YD/POJ0V6x/R5APWDOdO5R4CEBRNDDt0MRzeO9GMxlWerS80dDLupt6SNhDQNRCaackb+xmbJBqJ/6ubBvRFwAsmP/6CVgmtFdx2y4WKGN8HEX37yNdMGF6SxoC/ymypCTcCWksMSCMaQwAhmpIQH/GKr8rKq8JIZEAtkreocd9m1hUYQkLzJWTTgxdCNTRQiFccQN0MlK9n6JFR0o+QiFwt0Bc7VZYMKvCV+9c/8pTvZbqEEEaVeFMjz7J37CgSYhkqJz4U9sWFoITNrILbZW4QhLa8gDqJsR1tH0QZQSnAILivB2r00F6p+Zbdwwht1Vty7w5rYtDTxTX0YqjF0J+iCB40DOnid4MYZHJAFZ8VKkmRq/WDxQKYjHLTK0oPSFMzloIfaZdBhxa3XZ81bF3Y1t9Wihsry+ZRG1HRDl5TYV+C6tixXCej7bOl0sFmPoitG2MclZNkzGtByaPU5MjwQAN7UCnQJkP2Lf056Gjwv1BLAwQUAAAACAB9AwFbOMfeNwISAABLNwAAGgAAAGFuc2libGUvbW9kdWxlcy9jb21tYW5kLnB5vVv9cuM2kv+fT4H1XE5STqI8zmR2ootTmXOcbGoz46nEc3tX2SkWREIS1iShJUDJ2iRV+zT3YPck1934ICjJX0nqXFNjiQQajf78dQN+xiYfT1iuClkvZ6w1i8krfJIkz9iFWu8auVyZGRvmI3Z2+vxszN7IfMVFyb4Sf+K8Zp9X9ntaiBV8/3JZcVmmuaq+GDNeF0yZlWj0UWIvx+xa6ZVU7M9tw42qJPvc3LiPX/Jay3kpiBRM/+bte/aNqEXDS/aunZcyZ9/JXNRasM0n6em/saEWgl1cvfvvb99+w1TDVsas9Ww63W636bJuU9Usp6WdoafLdTmBWam5NaMkWTSqYlm2aE3biCxjslqrxgD7tTLcSFXrJEm+urp4/+by7fXr62+v3rJz1gwGg2QymSSVKtpSzECEVQU7TvQKJmeF0Hkj1zh7xi5vRd4a4YdopmpmeLMURicbEA8MynhRiGLGVlIb1cicl0lMImH4M2HXK8HeDL1s5q0sjaxTR3fELC9A+0ZoBpL3K7KaV4ItVFmqrSjYfMc4K2ElphZMr3kuJoUoZSUNvAS+2krURqfxoku5EXUgt5VlyeaCCbuxAjfE4ZEWpcjxe62A+x4BN3WoR3Y2yBYprBuVC61hilk1ql2uiG29EmU5ZloxtQaVkw6A4RvQ8PDk45PRGH9/7n5/4X7/7H7/+8mITA8+/utJtNpWNTeOJcZel1qNmag3slE1bpdteCM5SFWDBARrhFblBtjaSM7e7cxK1WOi4lkDa7saits1rJR5kWVAQ9vFkUYpFoa1NfhHvQRKckEEKm7ylSgCJ+/BhM1RtdJSQakwfadaVguSlYBZC8HRYiM5K5Y38BDFFGzCcH2DxsANMSW4lqJhRsEWOVICJ8blVQ07bzVEgbstYux5XnOt4b8GrMqA/bp5SOZiCKNBBt8NcV12I3Yg9mLsvbFQuU4j1566z9MSuNZm2oiFaESdi4yv16IuwGH1dF3y3VypG505cjpdmap8hiuMPEvg8q1GneQVbDrwFmRzKTESgd0vGoGu0FTBmmHq/jQmNcjn761sRGGVjZsTt7xal5HAv4apf5F1obbaO/SY2OgrdGuH4O9s31dlrQ0oIk3ErYEN6wxERNImq88WDV/iNxsBJozn9BipYNAwppFz8ED9wOu04duk+2qpgRnmNxnwIWZeiqwQBgK4nrHtSpaiF0OkAfdeoGR4M5em4c2OTD2nQInOrNv538D/0bhoItLHfcIbASSMzDVQYRDqNEqcTFWPplfDRlRqAx/B3a2vc/hHDsshKEBQ9ezpdo2xeYaaMhKCJPEsF4u9bYRxNdg1PQUjMqh1PyaMWLRl6Z75MbD9tdLylh6D5I7Pcbziy2NxwE46DOJoizTcRujgXJ2Lhkg0Rjv1Vgeu9S9/unpzOYqiL5LBeC5gnIBf6IXomxgiVE956O9tnQYWvl2AgP1CqNMoNI1RSfCoH7/AsGsKwRSWUNfaSNPiztBY8hXoqy0LZnUJJLrFfhBkE/85XPBSixF+LqSmlWkPmADJlAyaBPG94WUrrBmUEIQw7XtJWbpmt4akC2HB2YBY8LYE1ZimtQrfS6wnZ+nzlyfwBv0/6yzhqIKihNXPqXH40OBNIG/i8S4xA6HGiRd9s4VtdDEGkzKmqcDRCCdCIJpFO4RVHsdntzQIahOTwExPXyE7k6k9QPUdWlAfPzhFAGKAbIxxlPIGdzLo9vueQjAyQFrmGyUL9vdWGZQU6dTZubUVQodbqdF2IRKCUNaNwJQj61w1DcSScseGsROcQHS1kjsZdcte1TCOgIPVyTBoaYTRHd8Q844zG/1hAxaAbGSB5k1BDDhKGdATfh6xyKpWm3h0eoeJkYW5wBarYA1Su1vgr9kCgi1hNFh1CMk0F+wsPR2xZanmOBkkU6fWaclJcZM4B1AXpvEdyAf2BwHDAIAEKYg1+4+hRz4j5HzPLGEU/KMI3QWQKBB3L3GWe/z/sqO7dvLwLvgCvapLLHubONTXafqK9LUqZPP4vV1QPERzVZZJmA2WqiAdOjkCl7UHRM6D7mKADEYbqL7uCUcUP8m6YRxi9tg17epo/zbi67XI5UIidEV/S4/EkkO7fRHYwIdZLbalrEUsk8NIu3Oo4yjLoFjtoz6GZIDmFtGBvh11fGl3VHDD7/KoV5YzWCAT1drsMgRJ98kKhzIaynAVzai8I/iGWG+Ba6rWTOGXaADo1Yj1YUP3MnC/FMDHvHNMGG4dgfoWAI8LynGC2K9ywDn4jiZg6rdA+mL4OZUyX9D/P49sKY3VUD0KGJymUEoB3dvFHlNFeLjpqLwDpEKYn3iBvMQh3TdAF2E9hsiSqgQFyR9StS3uQhlrAUcoAqFC8aHeAYoC0BfrIjnswCKLCr1Ew7QGrcDzcgic7ypwtysoRgGi2VFe8J3nj6NQZoUH79DLRz7sd15io8aBq8IPonuUF4fgNfb1l6qDuPd1KzGY5aIBBF3bWFYoYQVBQc2XBlIHli86iIzRzuJLYMpuEPIwCjOKaFSq+J1R+PSxBpaM8DayI2zFY8OFFmRfYdtj2rEXpwwQ2BFZuOxHfGM95qOOTTo1wjxqkli5kYKZL3RBYqbVxF23MtXOsL8yLE4Fosey+kZCeCiCYBDZXA3lsgZLmVkLQ7x4UKKhJGBFyi/OdyHPvEi9F644YFFuq2a7KRlVrseKtUf4zYT9rpVfRLIREGHIg/QO3lZHiXoO7WAyiuMr+gF2wTQKUHECAcTVNjXaac3eX389eUXxmIoAD3vAAlRhiwoL6aTWAOVSm4IrCGC1wDaONNh8sEHsTolqm6cgBq9bE8zOoTG5jlpBF8M51+LlC0B6UIJD7aBmyYT5htuBOKDEvfutTRX3DUDujrw/osKEt2alGh/xX9uR7AKj2rXglXveb5Um2DBMLv/r9Zt3313+EDqIhGVn7HtSAixuLJIXS3S8hrI4Ju07IuIMBGfYVJh8ilMJqtmZM1bt6FHyjGqWCYHeoQXIo6inQ427rgoFI8CgjamzY66t4yA3RXw0NWqKdoIa2otzDPAayKc1bIDNoMHoPv6nrW6mc1lPKyiwMk8RtMGKeUZgH34TkHRB8Pxg+Ye3qFUl+nvUAoOAEQ4jIMNklZZj37cCwu4Bdj1Yr6XlC21XsGpksRQb0DfXUXD9bULc4+f3kaQtEX0TyBUrhwyhWAdQjQ5sxqaYFSLnb90W0Q3U7tuX5bJ64gbv35hn3kF51BY2mzBsdWAe4SnYDTyY2ozX1vs1MayntjXmood3/nupbi5gmvDw236jMbPATl/BVN2ErTxC6VgksyEWzD0nEgANw3fq+Pe9aLxnrLR1mxd4s3OutHGuFKVgiK9AkA4RvAcFyL7nQ9hecFRQO7acOOxRTBC1Qt4fuFcDWw88ZGRd3wSj9506iZsdDUUmMuntSoJIsXUeBhTzO18/xjpj17I5lTRD5Cp5G3XmqaPBjX7iDv3SsEvUkH8+2XQfJ4WYt8voe6nqpVqb8MQ26hBa7b+ZTKh34mecdyNtT2V/PLZcsZbjZSeCH/hCAN4mDAQ6xFOComtbOgTucTt7XW75TgfEhMUIIVZjDzwcdKmxR4040YKYh5LrTz9BJkXY+7Ol98sve1nWARlK799fXr//PhwPVnqJ0u6dBTqQTDQw5WOVyYnvZK/I1NTxmrFr7GgCpm7MAbG4/2dBMu6LxjIjK5Het4ztBvhVBmenz/84Of1scvYZOzubnX4ye/EqPX31yfOzV4NEWAN6xNrokr/Pyi9efvrHQVKI0vBHrk1jn7z66ewU/6Wnp88/PftskNj2wL1LYklYcIhwVvVPWe2ibNFu0JnxjJQ1fD6X5ktdQrx6bl3bPao4DmT/+8//IZ5E0zyOJxiomqewVGp/hMNzDNbgomrG3kJ8bSHgU8EHPhvy4iBxHeoHNGLPmX2hdy9DrkHtOEowGIh8pegDonKVNPm9K1rKeItBsOEpqwR4NLKP2xndu7Sso5XZqdN+RqjwKTYAlXWJvY3aAsonbJf92P46q/jgzOIpzJJx/DZen2ouUMHiHMsxBUl3vwISnkBn9d+xM+w/K+0/6VUpbt0dDR+nLSrIwOtLnULOlLm/s+FKsTcWNtw9yR6QpkbcGvhcb0RDDS9HxSgAW0ZuANLAx/nO4FEcfMLhDxPNVVnaDBMISp3RIRZMSRKIaQuomWU9HM0Syn7PerjStwe0P5f3q4WjKDxACeASD6YQcrn8ihDMEV1R46ZQ9cAA8fXONj+QoOtl0SUFpQj3Qn7E9Odv7PzB0Xh7dX05g6iuW+oegd3goTrQAko3Yk1WpHd17k4qc2EPRWm2Y/e8r5WhL/kDesmwK3VeyNx07/Ang4o+I6Co7duu+WnfQ6LXGdXt9j2a7PkA0ydYnevQnn9NZ479mYiD4ilo5TDFn4+dDyBEDvbmEI6OJyF62h/UdaqOcnzsnPge1q+pcd7nwhXBD/DhWoQPDXtGUcIt1/XHYA1sKmNlEbXP7d0Cti7bpax7ZKiLb9fylyaOiv3ggOFpe98/BXj87Oij67HqrLv9QKPtCHudxDbDz33fzJrgj4PI3iCUBZs4HEiP3ZDOIg7Hde/cYHTeI+t2ftCN2xyOo8LoQ1xeHGHNvnDDnJkcDnMv3DB7SnMwiB7HQ2LV3jE8HhKm4onNkeF9bQd5HrrQMckejgICLqht6SC3kjpcpYLtDWzmG7AhsxmVLQXkuNaoCR0GUcUbu4C1FVT/TwOH6gczRnYPpbAFEvBgMLDfIPX6b00+wIxJJTM2QsIXQu7dV9h294XQbfcVagsi94vdlLtcZi23A2FoW92tGCekLW/q4clrjT1937s8S1/YrnzXX4/N011hwJIN3kTnFKFvFkpttwjwaVzVOvhID9IT9lHEU7i21fcP3FvYz5AwBnoExCX8nZJJDEfs/Bw2bu/ZuTGbbpPNjyjfD0Dt7NOX8VOUGD4+gY34XEvXGk/2BbTgssz+plU9/PjjZhQYIl7s5b6nLUhnRtFtM3Jf1/EmDrrLB4/lpa/srtsTRRFCTinlbHspL4ljTCTYjXOL17YRrEPb33ZStV8zQjFEEFs3edkWInMDXdA/4OTHAKhw3tiiUMyyLXxYQjzKVEM0cszCNeAHogcDJMLORqwhG1N6gunoq0jXeTPIGV3og9tSEFB0qB9Hao/n7HHg/aw4geGPaXYdLfxRAPeQgjtWjMwZIRAbfnt1iZTH7OoH+jDC9pTo04hMZPC+9h0NG0oOLxWEOnfGwJ/AmxwgHUbO9IDdPIuu/PkbdN6Zx+4QTRp7xOkwALZFdThcRG92GWTqUoSXt1v22J1CvcLLPhw94S/4ydq4AFM5OuYrCSMcv3ReiUzeyLUmC5AFpARlzyRh2ejKCBtyrVuELN7V/LFpsIn4Yo57hlVHiv+FQ9Y7lXTykUXcUc/JCQ0jnOMC49zQ7Wbc5yAi6bIDUXVHn14BsEhHyedxRGpXX13NAOCswS7gWbJP0sWg06eJbr87vy9Cf9Ycx50gkmhAT6Y4qJOrJ/Fr5dpnsS/fHnuPlu8hRQ+Ejsj5XjHDZv1GDtIsEDf7HojRykEFpEKtPaevcJfDtU86HQxBd8htmqY9PdzjciQCxBK4ii+00/ChVtvhKNnb1TgWnP+CqOVDh69ARf4Q1KWAqOLpPtKpddbWmi+EK9DcvXk6ScbYTjCmJ9xf8YM983PClWNmm9jUqD8n6HCAN0e/eT0HK/G0JcMPVL8d/SOAWLgI4x7SQz8aPrN1mL2qQFE6Ctx7AXtrLza1a3uHgu6CLPApwle8fnoEqJwehSkX/q876G4m3ZxAl3TW1rtgchK7uw9SwO5b264IYcE/O/B955SdF8Tvn/nrIFSZ2Uvm1mvcA0iHVRvcBTCIBmyxv0TsaARMQhK0DR+6MAcJlGIj+qn8B925Z/a8hc8lIKdd5Obeo9zlpm6vXsXRi74u/SUYr3im6KI8uM+8NeFPOirECA5KIXP0VxZznt/E2rJlwAcLZSj/h+UnEZNHDXB/xuh4vIiGBWpeDATB9+JMCLW9ifbpKG0saj/5a/PX+mRvxRBe+jPp6cHMSBNkxn8AO54dM+QBIMjJP0Sj4r7w4DHA+o7IncCqGZ2/ZhkVH1mG/bssG9j1bTMv+T9QSwMEFAAAAAgAfQMBWwAAAAACAAAAAAAAABsAAABhbnNpYmxlL21vZHVsZXMvX19pbml0X18ucHkDAFBLAQIUAxQAAAAIAH0DAVv+zP6pYgAAAHgAAAATAAAAAAAAAAAAAACAAQAAAABhbnNpYmxlL19faW5pdF9fLnB5UEsBAhQDFAAAAAgAfQMBW53F8Ws3AAAASAAAACAAAAAAAAAAAAAAAIABkwAAAGFuc2libGUvbW9kdWxlX3V0aWxzL19faW5pdF9fLnB5UEsBAhQDFAAAAAgAfQMBWxjsw9jdWAAAE1EBAB0AAAAAAAAAAAAAAIABCAEAAGFuc2libGUvbW9kdWxlX3V0aWxzL2Jhc2ljLnB5UEsBAhQDFAAAAAgAfQMBW1MSsE1DAQAAIAIAAB0AAAAAAAAAAAAAAIABIFoAAGFuc2libGUvbW9kdWxlX3V0aWxzL190ZXh0LnB5UEsBAhQDFAAAAAgAfQMBW3uA+sulAgAAygUAACUAAAAAAAAAAAAAAIABnlsAAGFuc2libGUvbW9kdWxlX3V0aWxzL2NvbW1vbi9fdXRpbHMucHlQSwECFAMUAAAACAB9AwFbAAAAAAIAAAAAAAAAJwAAAAAAAAAAAAAAgAGGXgAAYW5zaWJsZS9tb2R1bGVfdXRpbHMvY29tbW9uL19faW5pdF9fLnB5UEsBAhQDFAAAAAgAfQMBW9/9CyjtCgAA7C4AACcAAAAAAAAAAAAAAIABzV4AAGFuc2libGUvbW9kdWxlX3V0aWxzL2NvbW1vbi9hcmdfc3BlYy5weVBLAQIUAxQAAAAIAH0DAVtRBPMleQUAAAoPAAAqAAAAAAAAAAAAAACAAf9pAABhbnNpYmxlL21vZHVsZV91dGlscy9jb21tb24vY29sbGVjdGlvbnMucHlQSwECFAMUAAAACAB9AwFbykH1MRYFAACmCwAAIwAAAAAAAAAAAAAAgAHAbwAAYW5zaWJsZS9tb2R1bGVfdXRpbHMvY29tbW9uL2ZpbGUucHlQSwECFAMUAAAACAB9AwFbzOnbldkDAAD4CAAAJQAAAAAAAAAAAAAAgAEXdQAAYW5zaWJsZS9tb2R1bGVfdXRpbHMvY29tbW9uL2xvY2FsZS5weVBLAQIUAxQAAAAIAH0DAVulkAp0iSEAALeRAAApAAAAAAAAAAAAAACAATN5AABhbnNpYmxlL21vZHVsZV91dGlscy9jb21tb24vcGFyYW1ldGVycy5weVBLAQIUAxQAAAAIAH0DAVsPJ7hs5wMAAOkIAAAmAAAAAAAAAAAAAACAAQObAABhbnNpYmxlL21vZHVsZV91dGlscy9jb21tb24vcHJvY2Vzcy5weVBLAQIUAxQAAAAIAH0DAVsxIUzEDgcAADwVAAAnAAAAAAAAAAAAAACAAS6fAABhbnNpYmxlL21vZHVsZV91dGlscy9jb21tb24vc3lzX2luZm8ucHlQSwECFAMUAAAACAB9AwFbfyqVUVQMAAB7MgAALgAAAAAAAAAAAAAAgAGBpgAAYW5zaWJsZS9tb2R1bGVfdXRpbHMvY29tbW9uL3RleHQvY29udmVydGVycy5weVBLAQIUAxQAAAAIAH0DAVsAAAAAAgAAAAAAAAAsAAAAAAAAAAAAAACAASGzAABhbnNpYmxlL21vZHVsZV91dGlscy9jb21tb24vdGV4dC9fX2luaXRfXy5weVBLAQIUAxQAAAAIAH0DAVvibWrivAYAAJYRAAAuAAAAAAAAAAAAAACAAW2zAABhbnNpYmxlL21vZHVsZV91dGlscy9jb21tb24vdGV4dC9mb3JtYXR0ZXJzLnB5UEsBAhQDFAAAAAgAfQMBWx58Aj26EQAArkwAACkAAAAAAAAAAAAAAIABdboAAGFuc2libGUvbW9kdWxlX3V0aWxzL2NvbW1vbi92YWxpZGF0aW9uLnB5UEsBAhQDFAAAAAgAfQMBW+6BqgsuAgAAVQUAACcAAAAAAAAAAAAAAIABdswAAGFuc2libGUvbW9kdWxlX3V0aWxzL2NvbW1vbi93YXJuaW5ncy5weVBLAQIUAxQAAAAIAH0DAVsybu8w8AQAAKANAAAmAAAAAAAAAAAAAACAAenOAABhbnNpYmxlL21vZHVsZV91dGlscy9jb21wYXQvc2VsaW51eC5weVBLAQIUAxQAAAAIAH0DAVsAAAAAAgAAAAAAAAAnAAAAAAAAAAAAAACAAR3UAABhbnNpYmxlL21vZHVsZV91dGlscy9jb21wYXQvX19pbml0X18ucHlQSwECFAMUAAAACAB9AwFbrlnptgoEAACXBwAAJwAAAAAAAAAAAAAAgAFk1AAAYW5zaWJsZS9tb2R1bGVfdXRpbHMvZGlzdHJvL19faW5pdF9fLnB5UEsBAhQDFAAAAAgAfQMBW47ROJVzLQAAsMEAACYAAAAAAAAAAAAAAIABs9gAAGFuc2libGUvbW9kdWxlX3V0aWxzL2Rpc3Ryby9fZGlzdHJvLnB5UEsBAhQDFAAAAAgAfQMBW31sJGy2AwAAEQ0AAB4AAAAAAAAAAAAAAIABagYBAGFuc2libGUvbW9kdWxlX3V0aWxzL2Vycm9ycy5weVBLAQIUAxQAAAAIAH0DAVtETuJdBAIAACUEAAAsAAAAAAAAAAAAAACAAVwKAQBhbnNpYmxlL21vZHVsZV91dGlscy9wYXJzaW5nL2NvbnZlcnRfYm9vbC5weVBLAQIUAxQAAAAIAH0DAVsAAAAAAgAAAAAAAAAoAAAAAAAAAAAAAACAAaoMAQBhbnNpYmxlL21vZHVsZV91dGlscy9wYXJzaW5nL19faW5pdF9fLnB5UEsBAhQDFAAAAAgAfQMBWzG99byOBQAAiQsAACIAAAAAAAAAAAAAAIAB8gwBAGFuc2libGUvbW9kdWxlX3V0aWxzL3B5Y29tcGF0MjQucHlQSwECFAMUAAAACAB9AwFbxElsFOEhAACiiAAAJAAAAAAAAAAAAAAAgAHAEgEAYW5zaWJsZS9tb2R1bGVfdXRpbHMvc2l4L19faW5pdF9fLnB5UEsBAhQDFAAAAAgAfQMBWzjH3jcCEgAASzcAABoAAAAAAAAAAAAAAIAB4zQBAGFuc2libGUvbW9kdWxlcy9jb21tYW5kLnB5UEsBAhQDFAAAAAgAfQMBWwAAAAACAAAAAAAAABsAAAAAAAAAAAAAAIABHUcBAGFuc2libGUvbW9kdWxlcy9fX2luaXRfXy5weVBLBQYAAAAAHQAdAF0JAABYRwEAAAA='
    def invoke_module(modlib_path, temp_path, json_params):
        z = zipfile.ZipFile(modlib_path, mode='a')
        sitecustomize = u'import sys\nsys.path.insert(0,"%s")\n' % modlib_path
        sitecustomize = sitecustomize.encode('utf-8')
        zinfo = zipfile.ZipInfo()
        zinfo.filename = 'sitecustomize.py'
        zinfo.date_time = (2025, 8, 1, 0, 37, 10)
        z.writestr(zinfo, sitecustomize)
        z.close()
        sys.path.insert(0, modlib_path)
        from ansible.module_utils import basic
        basic._ANSIBLE_ARGS = json_params

        runpy.run_module(mod_name='ansible.modules.command', init_globals=dict(_module_fqn='ansible.modules.command', _modlib_path=modlib_path),
                         run_name='__main__', alter_sys=True)
        print('{"msg": "New-style module did not handle its own exit", "failed": true}')
        sys.exit(1)
    def debug(command, zipped_mod, json_params):
        basedir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'debug_dir')
        args_path = os.path.join(basedir, 'args')
        if command == 'explode':
            z = zipfile.ZipFile(zipped_mod)
            for filename in z.namelist():
                if filename.startswith('/'):
                    raise Exception('Something wrong with this module zip file: should not contain absolute paths')
                dest_filename = os.path.join(basedir, filename)
                if dest_filename.endswith(os.path.sep) and not os.path.exists(dest_filename):
                    os.makedirs(dest_filename)
                else:
                    directory = os.path.dirname(dest_filename)
                    if not os.path.exists(directory):
                        os.makedirs(directory)
                    f = open(dest_filename, 'wb')
                    f.write(z.read(filename))
                    f.close()
            f = open(args_path, 'wb')
            f.write(json_params)
            f.close()
            print('Module expanded into:')
            print('%s' % basedir)
            exitcode = 0
        elif command == 'execute':
            sys.path.insert(0, basedir)
            with open(args_path, 'rb') as f:
                json_params = f.read()
            from ansible.module_utils import basic
            basic._ANSIBLE_ARGS = json_params
            runpy.run_module(mod_name='ansible.modules.command', init_globals=None, run_name='__main__', alter_sys=True)
            print('{"msg": "New-style module did not handle its own exit", "failed": true}')
            sys.exit(1)
        else:
            print('WARNING: Unknown debug command.  Doing nothing.')
            exitcode = 0
        return exitcode
    ANSIBALLZ_PARAMS = '{"ANSIBLE_MODULE_ARGS": {"chdir": "/usr/local/bin/", "_raw_params": "xoa-updater --token JDJhJDEwJHEwUmpOeVlia1JhNUh6WS5Rd0hEeWV0RjBsQmtXU094SWNlN0JLMHpab0VrdUZMMUoyT1k2 --upgrade ", "_ansible_check_mode": false, "_ansible_no_log": false, "_ansible_debug": false, "_ansible_diff": false, "// Port of python's argparse module, version 3.9.0:
// https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py

'use strict'

// Copyright (C) 2010-2020 Python Software Foundation.
// Copyright (C) 2020 argparse.js authors

/*
 * Command-line parsing library
 *
 * This module is an optparse-inspired command-line parsing library that:
 *
 *     - handles both optional and positional arguments
 *     - produces highly informative usage messages
 *     - supports parsers that dispatch to sub-parsers
 *
 * The following is a simple usage example that sums integers from the
 * command-line and writes the result to a file::
 *
 *     parser = argparse.ArgumentParser(
 *         description='sum the integers at the command line')
 *     parser.add_argument(
 *         'integers', metavar='int', nargs='+', type=int,
 *         help='an integer to be summed')
 *     parser.add_argument(
 *         '--log', default=sys.stdout, type=argparse.FileType('w'),
 *         help='the file where the sum should be written')
 *     args = parser.parse_args()
 *     args.log.write('%s' % sum(args.integers))
 *     args.log.close()
 *
 * The module contains the following public classes:
 *
 *     - ArgumentParser -- The main entry point for command-line parsing. As the
 *         example above shows, the add_argument() method is used to populate
 *         the parser with actions for optional and positional arguments. Then
 *         the parse_args() method is invoked to convert the args at the
 *         command-line into an object with attributes.
 *
 *     - ArgumentError -- The exception raised by ArgumentParser objects when
 *         there are errors with the parser's actions. Errors raised while
 *         parsing the command-line are caught by ArgumentParser and emitted
 *         as command-line messages.
 *
 *     - FileType -- A factory for defining types of files to be created. As the
 *         example above shows, instances of FileType are typically passed as
 *         the type= argument of add_argument() calls.
 *
 *     - Action -- The base class for parser actions. Typically actions are
 *         selected by passing strings like 'store_true' or 'append_const' to
 *         the action= argument of add_argument(). However, for greater
 *         customization of ArgumentParser actions, subclasses of Action may
 *         be defined and passed as the action= argument.
 *
 *     - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
 *         ArgumentDefaultsHelpFormatter -- Formatter classes which
 *         may be passed as the formatter_class= argument to the
 *         ArgumentParser constructor. HelpFormatter is the default,
 *         RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
 *         not to change the formatting for help text, and
 *         ArgumentDefaultsHelpFormatter adds information about argument defaults
 *         to the help.
 *
 * All other classes in this module are considered implementation details.
 * (Also note that HelpFormatter and RawDescriptionHelpFormatter are only
 * considered public as object names -- the API of the formatter objects is
 * still considered an implementation detail.)
 */

const SUPPRESS = '==SUPPRESS=='

const OPTIONAL = '?'
const ZERO_OR_MORE = '*'
const ONE_OR_MORE = '+'
const PARSER = 'A...'
const REMAINDER = '...'
const _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'


// ==================================
// Utility functions used for porting
// ==================================
const assert = require('assert')
const util = require('util')
const fs = require('fs')
const sub = require('./lib/sub')
const path = require('path')
const repr = util.inspect

function get_argv() {
    // omit first argument (which is assumed to be interpreter - `node`, `coffee`, `ts-node`, etc.)
    return process.argv.slice(1)
}

function get_terminal_size() {
    return {
        columns: +process.env.COLUMNS || process.stdout.columns || 80
    }
}

function hasattr(object, name) {
    return Object.prototype.hasOwnProperty.call(object, name)
}

function getattr(object, name, value) {
    return hasattr(object, name) ? object[name] : value
}

function setattr(object, name, value) {
    object[name] = value
}

function setdefault(object, name, value) {
    if (!hasattr(object, name)) object[name] = value
    return object[name]
}

function delattr(object, name) {
    delete object[name]
}

function range(from, to, step=1) {
    // range(10) is equivalent to range(0, 10)
    if (arguments.length === 1) [ to, from ] = [ from, 0 ]
    if (typeof from !== 'number' || typeof to !== 'number' || typeof step !== 'number') {
        throw new TypeError('argument cannot be interpreted as an integer')
    }
    if (step === 0) throw new TypeError('range() arg 3 must not be zero')

    let result = []
    if (step > 0) {
        for (let i = from; i < to; i += step) result.push(i)
    } else {
        for (let i = from; i > to; i += step) result.push(i)
    }
    return result
}

function splitlines(str, keepends = false) {
    let result
    if (!keepends) {
        result = str.split(/\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]/)
    } else {
        result = []
        let parts = str.split(/(\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029])/)
        for (let i = 0; i < parts.length; i += 2) {
            result.push(parts[i] + (i + 1 < parts.length ? parts[i + 1] : ''))
        }
    }
    if (!result[result.length - 1]) result.pop()
    return result
}

function _string_lstrip(string, prefix_chars) {
    let idx = 0
    while (idx < string.length && prefix_chars.includes(string[idx])) idx++
    return idx ? string.slice(idx) : string
}

function _string_split(string, sep, maxsplit) {
    let result = string.split(sep)
    if (result.length > maxsplit) {
        result = result.slice(0, maxsplit).concat([ result.slice(maxsplit).join(sep) ])
    }
    return result
}

function _array_equal(array1, array2) {
    if (array1.length !== array2.length) return false
    for (let i = 0; i < array1.length; i++) {
        if (array1[i] !== array2[i]) return false
    }
    return true
}

function _array_remove(array, item) {
    let idx = array.indexOf(item)
    if (idx === -1) throw new TypeError(sub('%r not in list', item))
    array.splice(idx, 1)
}

// normalize choices to array;
// this isn't required in python because `in` and `map` operators work with anything,
// but in js dealing with multiple types here is too clunky
function _choices_to_array(choices) {
    if (choices === undefined) {
        return []
    } else if (Array.isArray(choices)) {
        return choices
    } else if (choices !== null && typeof choices[Symbol.iterator] === 'function') {
        return Array.from(choices)
    } else if (typeof choices === 'object' && choices !== null) {
        return Object.keys(choices)
    } else {
        throw new Error(sub('invalid choices value: %r', choices))
    }
}

// decorator that allows a class to be called without new
function _callable(cls) {
    let result = { // object is needed for inferred class name
        [cls.name]: function (...args) {
            let this_class = new.target === result || !new.target
            return Reflect.construct(cls, args, this_class ? cls : new.target)
        }
    }
    result[cls.name].prototype = cls.prototype
    // fix default tag for toString, e.g. [object Action] instead of [object Object]
    cls.prototype[Symbol.toStringTag] = cls.name
    return result[cls.name]
}

function _alias(object, from, to) {
    try {
        let name = object.constructor.name
        Object.defineProperty(object, from, {
            value: util.deprecate(object[to], sub('%s.%s() is renamed to %s.%s()',
                name, from, name, to)),
            enumerable: false
        })
    } catch {}
}

// decorator that allows snake_case class methods to be called with camelCase and vice versa
function _camelcase_alias(_class) {
    for (let name of Object.getOwnPropertyNames(_class.prototype)) {
        let camelcase = name.replace(/\w_[a-z]/g, s => s[0] + s[2].toUpperCase())
        if (camelcase !== name) _alias(_class.prototype, camelcase, name)
    }
    return _class
}

function _to_legacy_name(key) {
    key = key.replace(/\w_[a-z]/g, s => s[0] + s[2].toUpperCase())
    if (key === 'default') key = 'defaultValue'
    if (key === 'const') key = 'constant'
    return key
}

function _to_new_name(key) {
    if (key === 'defaultValue') key = 'default'
    if (key === 'constant') key = 'const'
    key = key.replace(/[A-Z]/g, c => '_' + c.toLowerCase())
    return key
}

// parse options
let no_default = Symbol('no_default_value')
function _parse_opts(args, descriptor) {
    function get_name() {
        let stack = new Error().stack.split('\n')
            .map(x => x.match(/^    at (.*) \(.*\)$/))
            .filter(Boolean)
            .map(m => m[1])
            .map(fn => fn.match(/[^ .]*$/)[0])

        if (stack.length && stack[0] === get_name.name) stack.shift()
        if (stack.length && stack[0] === _parse_opts.name) stack.shift()
        return stack.length ? stack[0] : ''
    }

    args = Array.from(args)
    let kwargs = {}
    let result = []
    let last_opt = args.length && args[args.length - 1]

    if (typeof last_opt === 'object' && last_opt !== null && !Array.isArray(last_opt) &&
        (!last_opt.constructor || last_opt.constructor.name === 'Object')) {
        kwargs = Object.assign({}, args.pop())
    }

    // LEGACY (v1 compatibility): camelcase
    let renames = []
    for (let key of Object.keys(descriptor)) {
        let old_name = _to_legacy_name(key)
        if (old_name !== key && (old_name in kwargs)) {
            if (key in kwargs) {
                // default and defaultValue specified at the same time, happens often in old tests
                //throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), key))
            } else {
                kwargs[key] = kwargs[old_name]
            }
            renames.push([ old_name, key ])
            delete kwargs[old_name]
        }
    }
    if (renames.length) {
        let name = get_name()
        deprecate('camelcase_' + name, sub('%s(): following options are renamed: %s',
            name, renames.map(([ a, b ]) => sub('%r -> %r', a, b))))
    }
    // end

    let missing_positionals = []
    let positional_count = args.length

    for (let [ key, def ] of Object.entries(descriptor)) {
        if (key[0] === '*') {
            if (key.length > 0 && key[1] === '*') {
                // LEGACY (v1 compatibility): camelcase
                let renames = []
                for (let key of Object.keys(kwargs)) {
                    let new_name = _to_new_name(key)
                    if (new_name !== key && (key in kwargs)) {
                        if (new_name in kwargs) {
                            // default and defaultValue specified at the same time, happens often in old tests
                            //throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), new_name))
                        } else {
                            kwargs[new_name] = kwargs[key]
                        }
                        renames.push([ key, new_name ])
                        delete kwargs[key]
                    }
                }
                if (renames.length) {
                    let name = get_name()
                    deprecate('camelcase_' + name, sub('%s(): following options are renamed: %s',
                        name, renames.map(([ a, b ]) => sub('%r -> %r', a, b))))
                }
                // end
                result.push(kwargs)
                kwargs = {}
            } else {
                result.push(args)
                args = []
            }
        } else if (key in kwargs && args.length > 0) {
            throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), key))
        } else if (key in kwargs) {
            result.push(kwargs[key])
            delete kwargs[key]
        } else if (args.length > 0) {
            result.push(args.shift())
        } else if (def !== no_default) {
            result.push(def)
        } else {
            missing_positionals.push(key)
        }
    }

    if (Object.keys(kwargs).length) {
        throw new TypeError(sub('%s() got an unexpected keyword argument %r',
            get_name(), Object.keys(kwargs)[0]))
    }

    if (args.length) {
        let from = Object.entries(descriptor).filter(([ k, v ]) => k[0] !== '*' && v !== no_default).length
        let to = Object.entries(descriptor).filter(([ k ]) => k[0] !== '*').length
        throw new TypeError(sub('%s() takes %s positional argument%s but %s %s given',
            get_name(),
            from === to ? sub('from %s to %s', from, to) : to,
            from === to && to === 1 ? '' : 's',
            positional_count,
            positional_count === 1 ? 'was' : 'were'))
    }

    if (missing_positionals.length) {
        let strs = missing_positionals.map(repr)
        if (strs.length > 1) strs[strs.length - 1] = 'and ' + strs[strs.length - 1]
        let str_joined = strs.join(strs.length === 2 ? '' : ', ')
        throw new TypeError(sub('%s() missing %i required positional argument%s: %s',
            get_name(), strs.length, strs.length === 1 ? '' : 's', str_joined))
    }

    return result
}

let _deprecations = {}
function deprecate(id, string) {
    _deprecations[id] = _deprecations[id] || util.deprecate(() => {}, string)
    _deprecations[id]()
}


// =============================
// Utility functions and classes
// =============================
function _AttributeHolder(cls = Object) {
    /*
     *  Abstract base class that provides __repr__.
     *
     *  The __repr__ method returns a string in the format::
     *      ClassName(attr=name, attr=name, ...)
     *  The attributes are determined either by a class-level attribute,
     *  '_kwarg_names', or by inspecting the instance __dict__.
     */

    return class _AttributeHolder extends cls {
        [util.inspect.custom]() {
            let type_name = this.constructor.name
            let arg_strings = []
            let star_args = {}
            for (let arg of this._get_args()) {
                arg_strings.push(repr(arg))
            }
            for (let [ name, value ] of this._get_kwargs()) {
                if (/^[a-z_][a-z0-9_$]*$/i.test(name)) {
                    arg_strings.push(sub('%s=%r', name, value))
                } else {
                    star_args[name] = value
                }
            }
            if (Object.keys(star_args).length) {
                arg_strings.push(sub('**%s', repr(star_args)))
            }
            return sub('%s(%s)', type_name, arg_strings.join(', '))
        }

        toString() {
            return this[util.inspect.custom]()
        }

        _get_kwargs() {
            return Object.entries(this)
        }

        _get_args() {
            return []
        }
    }
}


function _copy_items(items) {
    if (items === undefined) {
        return []
    }
    return items.slice(0)
}


// ===============
// Formatting Help
// ===============
const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
    /*
     *  Formatter for generating usage messages and argument help strings.
     *
     *  Only the name of this class is considered a public API. All the methods
     *  provided by the class are considered an implementation detail.
     */

    constructor() {
        let [
            prog,
            indent_increment,
            max_help_position,
            width
        ] = _parse_opts(arguments, {
            prog: no_default,
            indent_increment: 2,
            max_help_position: 24,
            width: undefined
        })

        // default setting for width
        if (width === undefined) {
            width = get_terminal_size().columns
            width -= 2
        }

        this._prog = prog
        this._indent_increment = indent_increment
        this._max_help_position = Math.min(max_help_position,
                                      Math.max(width - 20, indent_increment * 2))
        this._width = width

        this._current_indent = 0
        this._level = 0
        this._action_max_length = 0

        this._root_section = this._Section(this, undefined)
        this._current_section = this._root_section

        this._whitespace_matcher = /[ \t\n\r\f\v]+/g // equivalent to python /\s+/ with ASCII flag
        this._long_break_matcher = /\n\n\n+/g
    }

    // ===============================
    // Section and indentation methods
    // ===============================
    _indent() {
        this._current_indent += this._indent_increment
        this._level += 1
    }

    _dedent() {
        this._current_indent -= this._indent_increment
        assert(this._current_indent >= 0, 'Indent decreased below 0.')
        this._level -= 1
    }

    _add_item(func, args) {
        this._current_section.items.push([ func, args ])
    }

    // ========================
    // Message building methods
    // ========================
    start_section(heading) {
        this._indent()
        let section = this._Section(this, this._current_section, heading)
        this._add_item(section.format_help.bind(section), [])
        this._current_section = section
    }

    end_section() {
        this._current_section = this._current_section.parent
        this._dedent()
    }

    add_text(text) {
        if (text !== SUPPRESS && text !== undefined) {
            this._add_item(this._format_text.bind(this), [text])
        }
    }

    add_usage(usage, actions, groups, prefix = undefined) {
        if (usage !== SUPPRESS) {
            let args = [ usage, actions, groups, prefix ]
            this._add_item(this._format_usage.bind(this), args)
        }
    }

    add_argument(action) {
        if (action.help !== SUPPRESS) {

            // find all invocations
            let invocations = [this._format_action_invocation(action)]
            for (let subaction of this._iter_indented_subactions(action)) {
                invocations.push(this._format_action_invocation(subaction))
            }

            // update the maximum item length
            let invocation_length = Math.max(...invocations.map(invocation => invocation.length))
            let action_length = invocation_length + this._current_indent
            this._action_max_length = Math.max(this._action_max_length,
                                               action_length)

            // add the item to the list
            this._add_item(this._format_action.bind(this), [action])
        }
    }

    add_arguments(actions) {
        for (let action of actions) {
            this.add_argument(action)
        }
    }

    // =======================
    // Help-formatting methods
    // =======================
    format_help() {
        let help = this._root_section.format_help()
        if (help) {
            help = help.replace(this._long_break_matcher, '\n\n')
            help = help.replace(/^\n+|\n+$/g, '') + '\n'
        }
        return help
    }

    _join_parts(part_strings) {
        return part_strings.filter(part => part && part !== SUPPRESS).join('')
    }

    _format_usage(usage, actions, groups, prefix) {
        if (prefix === undefined) {
            prefix = 'usage: '
        }

        // if usage is specified, use that
        if (usage !== undefined) {
            usage = sub(usage, { prog: this._prog })

        // if no optionals or positionals are available, usage is just prog
        } else if (usage === undefined && !actions.length) {
            usage = sub('%(prog)s', { prog: this._prog })

        // if optionals and positionals are available, calculate usage
        } else if (usage === undefined) {
            let prog = sub('%(prog)s', { prog: this._prog })

            // split optionals from positionals
            let optionals = []
            let positionals = []
            for (let action of actions) {
                if (action.option_strings.length) {
                    optionals.push(action)
                } else {
                    positionals.push(action)
                }
            }

            // build full usage string
            let action_usage = this._format_actions_usage([].concat(optionals).concat(positionals), groups)
            usage = [ prog, action_usage ].map(String).join(' ')

            // wrap the usage parts if it's too long
            let text_width = this._width - this._current_indent
            if (prefix.length + usage.length > text_width) {

                // break usage into wrappable parts
                let part_regexp = /\(.*?\)+(?=\s|$)|\[.*?\]+(?=\s|$)|\S+/g
                let opt_usage = this._format_actions_usage(optionals, groups)
                let pos_usage = this._format_actions_usage(positionals, groups)
                let opt_parts = opt_usage.match(part_regexp) || []
                let pos_parts = pos_usage.match(part_regexp) || []
                assert(opt_parts.join(' ') === opt_usage)
                assert(pos_parts.join(' ') === pos_usage)

                // helper for wrapping lines
                let get_lines = (parts, indent, prefix = undefined) => {
                    let lines = []
                    let line = []
                    let line_len
                    if (prefix !== undefined) {
                        line_len = prefix.length - 1
                    } else {
                        line_len = indent.length - 1
                    }
                    for (let part of parts) {
                        if (line_len + 1 + part.length > text_width && line) {
                            lines.push(indent + line.join(' '))
                            line = []
                            line_len = indent.length - 1
                        }
                        line.push(part)
                        line_len += part.length + 1
                    }
                    if (line.length) {
                        lines.push(indent + line.join(' '))
                    }
                    if (prefix !== undefined) {
                        lines[0] = lines[0].slice(indent.length)
                    }
                    return lines
                }

                let lines

                // if prog is short, follow it with optionals or positionals
                if (prefix.length + prog.length <= 0.75 * text_width) {
                    let indent = ' '.repeat(prefix.length + prog.length + 1)
                    if (opt_parts.length) {
                        lines = get_lines([prog].concat(opt_parts), indent, prefix)
                        lines = lines.concat(get_lines(pos_parts, indent))
                    } else if (pos_parts.length) {
                        lines = get_lines([prog].concat(pos_parts), indent, prefix)
                    } else {
                        lines = [prog]
                    }

                // if prog is long, put it on its own line
                } else {
                    let indent = ' '.repeat(prefix.length)
                    let parts = [].concat(opt_parts).concat(pos_parts)
                    lines = get_lines(parts, indent)
                    if (lines.length > 1) {
                        lines = []
                        lines = lines.concat(get_lines(opt_parts, indent))
                        lines = lines.concat(get_lines(pos_parts, indent))
                    }
                    lines = [prog].concat(lines)
                }

                // join lines into usage
                usage = lines.join('\n')
            }
        }

        // prefix with 'usage:'
        return sub('%s%s\n\n', prefix, usage)
    }

    _format_actions_usage(actions, groups) {
        // find group indices and identify actions in groups
        let group_actions = new Set()
        let inserts = {}
        for (let group of groups) {
            let start = actions.indexOf(group._group_actions[0])
            if (start === -1) {
                continue
            } else {
                let end = start + group._group_actions.length
                if (_array_equal(actions.slice(start, end), group._group_actions)) {
                    for (let action of group._group_actions) {
                        group_actions.add(action)
                    }
                    if (!group.required) {
                        if (start in inserts) {
                            inserts[start] += ' ['
                        } else {
                            inserts[start] = '['
                        }
                        if (end in inserts) {
                            inserts[end] += ']'
                        } else {
                            inserts[end] = ']'
                        }
                    } else {
                        if (start in inserts) {
                            inserts[start] += ' ('
                        } else {
                            inserts[start] = '('
                        }
                        if (end in inserts) {
                            inserts[end] += ')'
                        } else {
                            inserts[end] = ')'
                        }
                    }
                    for (let i of range(start + 1, end)) {
                        inserts[i] = '|'
                    }
                }
            }
        }

        // collect all actions format strings
        let parts = []
        for (let [ i, action ] of Object.entries(actions)) {

            // suppressed arguments are marked with None
            // remove | separators for suppressed arguments
            if (action.help === SUPPRESS) {
                parts.push(undefined)
                if (inserts[+i] === '|') {
                    delete inserts[+i]
                } else if (inserts[+i + 1] === '|') {
                    delete inserts[+i + 1]
                }

            // produce all arg strings
            } else if (!action.option_strings.length) {
                let default_value = this._get_default_metavar_for_positional(action)
                let part = this._format_args(action, default_value)

                // if it's in a group, strip the outer []
                if (group_actions.has(action)) {
                    if (part[0] === '[' && part[part.length - 1] === ']') {
                        part = part.slice(1, -1)
                    }
                }

                // add the action string to the list
                parts.push(part)

            // produce the first way to invoke the option in brackets
            } else {
                let option_string = action.option_strings[0]
                let part

                // if the Optional doesn't take a value, format is:
                //    -s or --long
                if (action.nargs === 0) {
                    part = action.format_usage()

                // if the Optional takes a value, format is:
                //    -s ARGS or --long ARGS
                } else {
                    let default_value = this._get_default_metavar_for_optional(action)
                    let args_string = this._format_args(action, default_value)
                    part = sub('%s %s', option_string, args_string)
                }

                // make it look optional if it's not required or in a group
                if (!action.required && !group_actions.has(action)) {
                    part = sub('[%s]', part)
                }

                // add the action string to the list
                parts.push(part)
            }
        }

        // insert things at the necessary indices
        for (let i of Object.keys(inserts).map(Number).sort((a, b) => b - a)) {
            parts.splice(+i, 0, inserts[+i])
        }

        // join all the action items with spaces
        let text = parts.filter(Boolean).join(' ')

        // clean up separators for mutually exclusive groups
        text = text.replace(/([\[(]) /g, '$1')
        text = text.replace(/ ([\])])/g, '$1')
        text = text.replace(/[\[(] *[\])]/g, '')
        text = text.replace(/\(([^|]*)\)/g, '$1', text)
        text = text.trim()

        // return the text
        return text
    }

    _format_text(text) {
        if (text.includes('%(prog)')) {
            text = sub(text, { prog: this._prog })
        }
        let text_width = Math.max(this._width - this._current_indent, 11)
        let indent = ' '.repeat(this._current_indent)
        return this._fill_text(text, text_width, indent) + '\n\n'
    }

    _format_action(action) {
        // determine the required width and the entry label
        let help_position = Math.min(this._action_max_length + 2,
                                     this._max_help_position)
        let help_width = Math.max(this._width - help_position, 11)
        let action_width = help_position - this._current_indent - 2
        let action_header = this._format_action_invocation(action)
        let indent_first

        // no help; start on same line and add a final newline
        if (!action.help) {
            let tup = [ this._current_indent, '', action_header ]
            action_header = sub('%*s%s\n', ...tup)

        // short action name; start on the same line and pad two spaces
        } else if (action_header.length <= action_width) {
            let tup = [ this._current_indent, '', action_width, action_header ]
            action_header = sub('%*s%-*s  ', ...tup)
            indent_first = 0

        // long action name; start on the next line
        } else {
            let tup = [ this._current_indent, '', action_header ]
            action_header = sub('%*s%s\n', ...tup)
            indent_first = help_position
        }

        // collect the pieces of the action help
        let parts = [action_header]

        // if there was help for the action, add lines of help text
        if (action.help) {
            let help_text = this._expand_help(action)
            let help_lines = this._split_lines(help_text, help_width)
            parts.push(sub('%*s%s\n', indent_first, '', help_lines[0]))
            for (let line of help_lines.slice(1)) {
                parts.push(sub('%*s%s\n', help_position, '', line))
            }

        // or add a newline if the description doesn't end with one
        } else if (!action_header.endsWith('\n')) {
            parts.push('\n')
        }

        // if there are any sub-actions, add their help as well
        for (let subaction of this._iter_indented_subactions(action)) {
            parts.push(this._format_action(subaction))
        }

        // return a single string
        return this._join_parts(parts)
    }

    _format_action_invocation(action) {
        if (!action.option_strings.length) {
            let default_value = this._get_default_metavar_for_positional(action)
            let metavar = this._metavar_formatter(action, default_value)(1)[0]
            return metavar

        } else {
            let parts = []

            // if the Optional doesn't take a value, format is:
            //    -s, --long
            if (action.nargs === 0) {
                parts = parts.concat(action.option_strings)

            // if the Optional takes a value, format is:
            //    -s ARGS, --long ARGS
            } else {
                let default_value = this._get_default_metavar_for_optional(action)
                let args_string = this._format_args(action, default_value)
                for (let option_string of action.option_strings) {
                    parts.push(sub('%s %s', option_string, args_string))
                }
            }

            return parts.join(', ')
        }
    }

    _metavar_formatter(action, default_metavar) {
        let result
        if (action.metavar !== undefined) {
            result = action.metavar
        } else if (action.choices !== undefined) {
            let choice_strs = _choices_to_array(action.choices).map(String)
            result = sub('{%s}', choice_strs.join(','))
        } else {
            result = default_metavar
        }

        function format(tuple_size) {
            if (Array.isArray(result)) {
                return result
            } else {
                return Array(tuple_size).fill(result)
            }
        }
        return format
    }

    _format_args(action, default_metavar) {
        let get_metavar = this._metavar_formatter(action, default_metavar)
        let result
        if (action.nargs === undefined) {
            result = sub('%s', ...get_metavar(1))
        } else if (action.nargs === OPTIONAL) {
            result = sub('[%s]', ...get_metavar(1))
        } else if (action.nargs === ZERO_OR_MORE) {
            let metavar = get_metavar(1)
            if (metavar.length === 2) {
                result = sub('[%s [%s ...]]', ...metavar)
            } else {
                result = sub('[%s ...]', ...metavar)
            }
        } else if (action.nargs === ONE_OR_MORE) {
            result = sub('%s [%s ...]', ...get_metavar(2))
        } else if (action.nargs === REMAINDER) {
            result = '...'
        } else if (action.nargs === PARSER) {
            result = sub('%s ...', ...get_metavar(1))
        } else if (action.nargs === SUPPRESS) {
            result = ''
        } else {
            let formats
            try {
                formats = range(action.nargs).map(() => '%s')
            } catch (err) {
                throw new TypeError('invalid nargs value')
            }
            result = sub(formats.join(' '), ...get_metavar(action.nargs))
        }
        return result
    }

    _expand_help(action) {
        let params = Object.assign({ prog: this._prog }, action)
        for (let name of Object.keys(params)) {
            if (params[name] === SUPPRESS) {
                delete params[name]
            }
        }
        for (let name of Object.keys(params)) {
            if (params[name] && params[name].name) {
                params[name] = params[name].name
            }
        }
        if (params.choices !== undefined) {
            let choices_str = _choices_to_array(params.choices).map(String).join(', ')
            params.choices = choices_str
        }
        // LEGACY (v1 compatibility): camelcase
        for (let key of Object.keys(params)) {
            let old_name = _to_legacy_name(key)
            if (old_name !== key) {
                params[old_name] = params[key]
            }
        }
        // end
        return sub(this._get_help_string(action), params)
    }

    * _iter_indented_subactions(action) {
        if (typeof action._get_subactions === 'function') {
            this._indent()
            yield* action._get_subactions()
            this._dedent()
        }
    }

    _split_lines(text, width) {
        text = text.replace(this._whitespace_matcher, ' ').trim()
        // The textwrap module is used only for formatting help.
        // Delay its import for speeding up the common usage of argparse.
        let textwrap = require('./lib/textwrap')
        return textwrap.wrap(text, { width })
    }

    _fill_text(text, width, indent) {
        text = text.replace(this._whitespace_matcher, ' ').trim()
        let textwrap = require('./lib/textwrap')
        return textwrap.fill(text, { width,
                                     initial_indent: indent,
                                     subsequent_indent: indent })
    }

    _get_help_string(action) {
        return action.help
    }

    _get_default_metavar_for_optional(action) {
        return action.dest.toUpperCase()
    }

    _get_default_metavar_for_positional(action) {
        return action.dest
    }
}))

HelpFormatter.prototype._Section = _callable(class _Section {

    constructor(formatter, parent, heading = undefined) {
        this.formatter = formatter
        this.parent = parent
        this.heading = heading
        this.items = []
    }

    format_help() {
        // format the indented section
        if (this.parent !== undefined) {
            this.formatter._indent()
        }
        let item_help = this.formatter._join_parts(this.items.map(([ func, args ]) => func.apply(null, args)))
        if (this.parent !== undefined) {
            this.formatter._dedent()
        }

        // return nothing if the section was empty
        if (!item_help) {
            return ''
        }

        // add the heading if the section was non-empty
        let heading
        if (this.heading !== SUPPRESS && this.heading !== undefined) {
            let current_indent = this.formatter._current_indent
            heading = sub('%*s%s:\n', current_indent, '', this.heading)
        } else {
            heading = ''
        }

        // join the section-initial newline, the heading and the help
        return this.formatter._join_parts(['\n', heading, item_help, '\n'])
    }
})


const RawDescriptionHelpFormatter = _camelcase_alias(_callable(class RawDescriptionHelpFormatter extends HelpFormatter {
    /*
     *  Help message formatter which retains any formatting in descriptions.
     *
     *  Only the name of this class is considered a public API. All the methods
     *  provided by the class are considered an implementation detail.
     */

    _fill_text(text, width, indent) {
        return splitlines(text, true).map(line => indent + line).join('')
    }
}))


const RawTextHelpFormatter = _camelcase_alias(_callable(class RawTextHelpFormatter extends RawDescriptionHelpFormatter {
    /*
     *  Help message formatter which retains formatting of all help text.
     *
     *  Only the name of this class is considered a public API. All the methods
     *  provided by the class are considered an implementation detail.
     */

    _split_lines(text/*, width*/) {
        return splitlines(text)
    }
}))


const ArgumentDefaultsHelpFormatter = _camelcase_alias(_callable(class ArgumentDefaultsHelpFormatter extends HelpFormatter {
    /*
     *  Help message formatter which adds default values to argument help.
     *
     *  Only the name of this class is considered a public API. All the methods
     *  provided by the class are considered an implementation detail.
     */

    _get_help_string(action) {
        let help = action.help
        // LEGACY (v1 compatibility): additional check for defaultValue needed
        if (!action.help.includes('%(default)') && !action.help.includes('%(defaultValue)')) {
            if (action.default !== SUPPRESS) {
                let defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
                if (action.option_strings.length || defaulting_nargs.includes(action.nargs)) {
                    help += ' (default: %(default)s)'
                }
            }
        }
        return help
    }
}))


const MetavarTypeHelpFormatter = _camelcase_alias(_callable(class MetavarTypeHelpFormatter extends HelpFormatter {
    /*
     *  Help message formatter which uses the argument 'type' as the default
     *  metavar value (instead of the argument 'dest')
     *
     *  Only the name of this class is considered a public API. All the methods
     *  provided by the class are considered an implementation detail.
     */

    _get_default_metavar_for_optional(action) {
        return typeof action.type === 'function' ? action.type.name : action.type
    }

    _get_default_metavar_for_positional(action) {
        return typeof action.type === 'function' ? action.type.name : action.type
    }
}))


// =====================
// Options and Arguments
// =====================
function _get_action_name(argument) {
    if (argument === undefined) {
        return undefined
    } else if (argument.option_strings.length) {
        return argument.option_strings.join('/')
    } else if (![ undefined, SUPPRESS ].includes(argument.metavar)) {
        return argument.metavar
    } else if (![ undefined, SUPPRESS ].includes(argument.dest)) {
        return argument.dest
    } else {
        return undefined
    }
}


const ArgumentError = _callable(class ArgumentError extends Error {
    /*
     *  An error from creating or using an argument (optional or positional).
     *
     *  The string value of this exception is the message, augmented with
     *  information about the argument that caused it.
     */

    constructor(argument, message) {
        super()
        this.name = 'ArgumentError'
        this._argument_name = _get_action_name(argument)
        this._message = message
        this.message = this.str()
    }

    str() {
        let format
        if (this._argument_name === undefined) {
            format = '%(message)s'
        } else {
            format = 'argument %(argument_name)s: %(message)s'
        }
        return sub(format, { message: this._message,
                             argument_name: this._argument_name })
    }
})


const ArgumentTypeError = _callable(class ArgumentTypeError extends Error {
    /*
     * An error from trying to convert a command line string to a type.
     */

    constructor(message) {
        super(message)
        this.name = 'ArgumentTypeError'
    }
})


// ==============
// Action classes
// ==============
const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(Function) {
    /*
     *  Information about how to convert command line strings to Python objects.
     *
     *  Action objects are used by an ArgumentParser to represent the information
     *  needed to parse a single argument from one or more strings from the
     *  command line. The keyword arguments to the Action constructor are also
     *  all attributes of Action instances.
     *
     *  Keyword Arguments:
     *
     *      - option_strings -- A list of command-line option strings which
     *          should be associated with this action.
     *
     *      - dest -- The name of the attribute to hold the created object(s)
     *
     *      - nargs -- The number of command-line arguments that should be
     *          consumed. By default, one argument will be consumed and a single
     *          value will be produced.  Other values include:
     *              - N (an integer) consumes N arguments (and produces a list)
     *              - '?' consumes zero or one arguments
     *              - '*' consumes zero or more arguments (and produces a list)
     *              - '+' consumes one or more arguments (and produces a list)
     *          Note that the difference between the default and nargs=1 is that
     *          with the default, a single value will be produced, while with
     *          nargs=1, a list containing a single value will be produced.
     *
     *      - const -- The value to be produced if the option is specified and the
     *          option uses an action that takes no values.
     *
     *      - default -- The value to be produced if the option is not specified.
     *
     *      - type -- A callable that accepts a single string argument, and
     *          returns the converted value.  The standard Python types str, int,
     *          float, and complex are useful examples of such callables.  If None,
     *          str is used.
     *
     *      - choices -- A container of values that should be allowed. If not None,
     *          after a command-line argument has been converted to the appropriate
     *          type, an exception will be raised if it is not a member of this
     *          collection.
     *
     *      - required -- True if the action must always be specified at the
     *          command line. This is only meaningful for optional command-line
     *          arguments.
     *
     *      - help -- The help string describing the argument.
     *
     *      - metavar -- The name to be used for the option's argument with the
     *          help string. If None, the 'dest' value will be used as the name.
     */

    constructor() {
        let [
            option_strings,
            dest,
            nargs,
            const_value,
            default_value,
            type,
            choices,
            required,
            help,
            metavar
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            nargs: undefined,
            const: undefined,
            default: undefined,
            type: undefined,
            choices: undefined,
            required: false,
            help: undefined,
            metavar: undefined
        })

        // when this class is called as a function, redirect it to .call() method of itself
        super('return arguments.callee.call.apply(arguments.callee, arguments)')

        this.option_strings = option_strings
        this.dest = dest
        this.nargs = nargs
        this.const = const_value
        this.default = default_value
        this.type = type
        this.choices = choices
        this.required = required
        this.help = help
        this.metavar = metavar
    }

    _get_kwargs() {
        let names = [
            'option_strings',
            'dest',
            'nargs',
            'const',
            'default',
            'type',
            'choices',
            'help',
            'metavar'
        ]
        return names.map(name => [ name, getattr(this, name) ])
    }

    format_usage() {
        return this.option_strings[0]
    }

    call(/*parser, namespace, values, option_string = undefined*/) {
        throw new Error('.call() not defined')
    }
}))


const BooleanOptionalAction = _camelcase_alias(_callable(class BooleanOptionalAction extends Action {

    constructor() {
        let [
            option_strings,
            dest,
            default_value,
            type,
            choices,
            required,
            help,
            metavar
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            default: undefined,
            type: undefined,
            choices: undefined,
            required: false,
            help: undefined,
            metavar: undefined
        })

        let _option_strings = []
        for (let option_string of option_strings) {
            _option_strings.push(option_string)

            if (option_string.startsWith('--')) {
                option_string = '--no-' + option_string.slice(2)
                _option_strings.push(option_string)
            }
        }

        if (help !== undefined && default_value !== undefined) {
            help += ` (default: ${default_value})`
        }

        super({
            option_strings: _option_strings,
            dest,
            nargs: 0,
            default: default_value,
            type,
            choices,
            required,
            help,
            metavar
        })
    }

    call(parser, namespace, values, option_string = undefined) {
        if (this.option_strings.includes(option_string)) {
            setattr(namespace, this.dest, !option_string.startsWith('--no-'))
        }
    }

    format_usage() {
        return this.option_strings.join(' | ')
    }
}))


const _StoreAction = _callable(class _StoreAction extends Action {

    constructor() {
        let [
            option_strings,
            dest,
            nargs,
            const_value,
            default_value,
            type,
            choices,
            required,
            help,
            metavar
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            nargs: undefined,
            const: undefined,
            default: undefined,
            type: undefined,
            choices: undefined,
            required: false,
            help: undefined,
            metavar: undefined
        })

        if (nargs === 0) {
            throw new TypeError('nargs for store actions must be != 0; if you ' +
                        'have nothing to store, actions such as store ' +
                        'true or store const may be more appropriate')
        }
        if (const_value !== undefined && nargs !== OPTIONAL) {
            throw new TypeError(sub('nargs must be %r to supply const', OPTIONAL))
        }
        super({
            option_strings,
            dest,
            nargs,
            const: const_value,
            default: default_value,
            type,
            choices,
            required,
            help,
            metavar
        })
    }

    call(parser, namespace, values/*, option_string = undefined*/) {
        setattr(namespace, this.dest, values)
    }
})


const _StoreConstAction = _callable(class _StoreConstAction extends Action {

    constructor() {
        let [
            option_strings,
            dest,
            const_value,
            default_value,
            required,
            help
            //, metavar
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            const: no_default,
            default: undefined,
            required: false,
            help: undefined,
            metavar: undefined
        })

        super({
            option_strings,
            dest,
            nargs: 0,
            const: const_value,
            default: default_value,
            required,
            help
        })
    }

    call(parser, namespace/*, values, option_string = undefined*/) {
        setattr(namespace, this.dest, this.const)
    }
})


const _StoreTrueAction = _callable(class _StoreTrueAction extends _StoreConstAction {

    constructor() {
        let [
            option_strings,
            dest,
            default_value,
            required,
            help
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            default: false,
            required: false,
            help: undefined
        })

        super({
            option_strings,
            dest,
            const: true,
            default: default_value,
            required,
            help
        })
    }
})


const _StoreFalseAction = _callable(class _StoreFalseAction extends _StoreConstAction {

    constructor() {
        let [
            option_strings,
            dest,
            default_value,
            required,
            help
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            default: true,
            required: false,
            help: undefined
        })

        super({
            option_strings,
            dest,
            const: false,
            default: default_value,
            required,
            help
        })
    }
})


const _AppendAction = _callable(class _AppendAction extends Action {

    constructor() {
        let [
            option_strings,
            dest,
            nargs,
            const_value,
            default_value,
            type,
            choices,
            required,
            help,
            metavar
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            nargs: undefined,
            const: undefined,
            default: undefined,
            type: undefined,
            choices: undefined,
            required: false,
            help: undefined,
            metavar: undefined
        })

        if (nargs === 0) {
            throw new TypeError('nargs for append actions must be != 0; if arg ' +
                        'strings are not supplying the value to append, ' +
                        'the append const action may be more appropriate')
        }
        if (const_value !== undefined && nargs !== OPTIONAL) {
            throw new TypeError(sub('nargs must be %r to supply const', OPTIONAL))
        }
        super({
            option_strings,
            dest,
            nargs,
            const: const_value,
            default: default_value,
            type,
            choices,
            required,
            help,
            metavar
        })
    }

    call(parser, namespace, values/*, option_string = undefined*/) {
        let items = getattr(namespace, this.dest, undefined)
        items = _copy_items(items)
        items.push(values)
        setattr(namespace, this.dest, items)
    }
})


const _AppendConstAction = _callable(class _AppendConstAction extends Action {

    constructor() {
        let [
            option_strings,
            dest,
            const_value,
            default_value,
            required,
            help,
            metavar
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            const: no_default,
            default: undefined,
            required: false,
            help: undefined,
            metavar: undefined
        })

        super({
            option_strings,
            dest,
            nargs: 0,
            const: const_value,
            default: default_value,
            required,
            help,
            metavar
        })
    }

    call(parser, namespace/*, values, option_string = undefined*/) {
        let items = getattr(namespace, this.dest, undefined)
        items = _copy_items(items)
        items.push(this.const)
        setattr(namespace, this.dest, items)
    }
})


const _CountAction = _callable(class _CountAction extends Action {

    constructor() {
        let [
            option_strings,
            dest,
            default_value,
            required,
            help
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: no_default,
            default: undefined,
            required: false,
            help: undefined
        })

        super({
            option_strings,
            dest,
            nargs: 0,
            default: default_value,
            required,
            help
        })
    }

    call(parser, namespace/*, values, option_string = undefined*/) {
        let count = getattr(namespace, this.dest, undefined)
        if (count === undefined) {
            count = 0
        }
        setattr(namespace, this.dest, count + 1)
    }
})


const _HelpAction = _callable(class _HelpAction extends Action {

    constructor() {
        let [
            option_strings,
            dest,
            default_value,
            help
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            dest: SUPPRESS,
            default: SUPPRESS,
            help: undefined
        })

        super({
            option_strings,
            dest,
            default: default_value,
            nargs: 0,
            help
        })
    }

    call(parser/*, namespace, values, option_string = undefined*/) {
        parser.print_help()
        parser.exit()
    }
})


const _VersionAction = _callable(class _VersionAction extends Action {

    constructor() {
        let [
            option_strings,
            version,
            dest,
            default_value,
            help
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            version: undefined,
            dest: SUPPRESS,
            default: SUPPRESS,
            help: "show program's version number and exit"
        })

        super({
            option_strings,
            dest,
            default: default_value,
            nargs: 0,
            help
        })
        this.version = version
    }

    call(parser/*, namespace, values, option_string = undefined*/) {
        let version = this.version
        if (version === undefined) {
            version = parser.version
        }
        let formatter = parser._get_formatter()
        formatter.add_text(version)
        parser._print_message(formatter.format_help(), process.stdout)
        parser.exit()
    }
})


const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction extends Action {

    constructor() {
        let [
            option_strings,
            prog,
            parser_class,
            dest,
            required,
            help,
            metavar
        ] = _parse_opts(arguments, {
            option_strings: no_default,
            prog: no_default,
            parser_class: no_default,
            dest: SUPPRESS,
            required: false,
            help: undefined,
            metavar: undefined
        })

        let name_parser_map = {}

        super({
            option_strings,
            dest,
            nargs: PARSER,
            choices: name_parser_map,
            required,
            help,
            metavar
        })

        this._prog_prefix = prog
        this._parser_class = parser_class
        this._name_parser_map = name_parser_map
        this._choices_actions = []
    }

    add_parser() {
        let [
            name,
            kwargs
        ] = _parse_opts(arguments, {
            name: no_default,
            '**kwargs': no_default
        })

        // set prog from the existing prefix
        if (kwargs.prog === undefined) {
            kwargs.prog = sub('%s %s', this._prog_prefix, name)
        }

        let aliases = getattr(kwargs, 'aliases', [])
        delete kwargs.aliases

        // create a pseudo-action to hold the choice help
        if ('help' in kwargs) {
            let help = kwargs.help
            delete kwargs.help
            let choice_action = this._ChoicesPseudoAction(name, aliases, help)
            this._choices_actions.push(choice_action)
        }

        // create the parser and add it to the map
        let parser = new this._parser_class(kwargs)
        this._name_parser_map[name] = parser

        // make parser available under aliases also
        for (let alias of aliases) {
            this._name_parser_map[alias] = parser
        }

        return parser
    }

    _get_subactions() {
        return this._choices_actions
    }

    call(parser, namespace, values/*, option_string = undefined*/) {
        let parser_name = values[0]
        let arg_strings = values.slice(1)

        // set the parser name if requested
        if (this.dest !== SUPPRESS) {
            setattr(namespace, this.dest, parser_name)
        }

        // select the parser
        if (hasattr(this._name_parser_map, parser_name)) {
            parser = this._name_parser_map[parser_name]
        } else {
            let args = {parser_name,
                        choices: this._name_parser_map.join(', ')}
            let msg = sub('unknown parser %(parser_name)r (choices: %(choices)s)', args)
            throw new ArgumentError(this, msg)
        }

        // parse all the remaining options into the namespace
        // store any unrecognized options on the object, so that the top
        // level parser can decide what to do with them

        // In case this subparser defines new defaults, we parse them
        // in a new namespace object and then update the original
        // namespace for the relevant parts.
        let subnamespace
        [ subnamespace, arg_strings ] = parser.parse_known_args(arg_strings, undefined)
        for (let [ key, value ] of Object.entries(subnamespace)) {
            setattr(namespace, key, value)
        }

        if (arg_strings.length) {
            setdefault(namespace, _UNRECOGNIZED_ARGS_ATTR, [])
            getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).push(...arg_strings)
        }
    }
}))


_SubParsersAction.prototype._ChoicesPseudoAction = _callable(class _ChoicesPseudoAction extends Action {
    constructor(name, aliases, help) {
        let metavar = name, dest = name
        if (aliases.length) {
            metavar += sub(' (%s)', aliases.join(', '))
        }
        super({ option_strings: [], dest, help, metavar })
    }
})


const _ExtendAction = _callable(class _ExtendAction extends _AppendAction {
    call(parser, namespace, values/*, option_string = undefined*/) {
        let items = getattr(namespace, this.dest, undefined)
        items = _copy_items(items)
        items = items.concat(values)
        setattr(namespace, this.dest, items)
    }
})


// ==============
// Type classes
// ==============
const FileType = _callable(class FileType extends Function {
    /*
     *  Factory for creating file object types
     *
     *  Instances of FileType are typically passed as type= arguments to the
     *  ArgumentParser add_argument() method.
     *
     *  Keyword Arguments:
     *      - mode -- A string indicating how the file is to be opened. Accepts the
     *          same values as the builtin open() function.
     *      - bufsize -- The file's desired buffer size. Accepts the same values as
     *          the builtin open() function.
     *      - encoding -- The file's encoding. Accepts the same values as the
     *          builtin open() function.
     *      - errors -- A string indicating how encoding and decoding errors are to
     *          be handled. Accepts the same value as the builtin open() function.
     */

    constructor() {
        let [
            flags,
            encoding,
            mode,
            autoClose,
            emitClose,
            start,
            end,
            highWaterMark,
            fs
        ] = _parse_opts(arguments, {
            flags: 'r',
            encoding: undefined,
            mode: undefined, // 0o666
            autoClose: undefined, // true
            emitClose: undefined, // false
            start: undefined, // 0
            end: undefined, // Infinity
            highWaterMark: undefined, // 64 * 1024
            fs: undefined
        })

        // when this class is called as a function, redirect it to .call() method of itself
        super('return arguments.callee.call.apply(arguments.callee, arguments)')

        Object.defineProperty(this, 'name', {
            get() {
                return sub('FileType(%r)', flags)
            }
        })
        this._flags = flags
        this._options = {}
        if (encoding !== undefined) this._options.encoding = encoding
        if (mode !== undefined) this._options.mode = mode
        if (autoClose !== undefined) this._options.autoClose = autoClose
        if (emitClose !== undefined) this._options.emitClose = emitClose
        if (start !== undefined) this._options.start = start
        if (end !== undefined) this._options.end = end
        if (highWaterMark !== undefined) this._options.highWaterMark = highWaterMark
        if (fs !== undefined) this._options.fs = fs
    }

    call(string) {
        // the special argument "-" means sys.std{in,out}
        if (string === '-') {
            if (this._flags.includes('r')) {
                return process.stdin
            } else if (this._flags.includes('w')) {
                return process.stdout
            } else {
                let msg = sub('argument "-" with mode %r', this._flags)
                throw new TypeError(msg)
            }
        }

        // all other arguments are used as file names
        let fd
        try {
            fd = fs.openSync(string, this._flags, this._options.mode)
        } catch (e) {
            let args = { filename: string, error: e.message }
            let message = "can't open '%(filename)s': %(error)s"
            throw new ArgumentTypeError(sub(message, args))
        }

        let options = Object.assign({ fd, flags: this._flags }, this._options)
        if (this._flags.includes('r')) {
            return fs.createReadStream(undefined, options)
        } else if (this._flags.includes('w')) {
            return fs.createWriteStream(undefined, options)
        } else {
            let msg = sub('argument "%s" with mode %r', string, this._flags)
            throw new TypeError(msg)
        }
    }

    [util.inspect.custom]() {
        let args = [ this._flags ]
        let kwargs = Object.entries(this._options).map(([ k, v ]) => {
            if (k === 'mode') v = { value: v, [util.inspect.custom]() { return '0o' + this.value.toString(8) } }
            return [ k, v ]
        })
        let args_str = []
                .concat(args.filter(arg => arg !== -1).map(repr))
                .concat(kwargs.filter(([/*kw*/, arg]) => arg !== undefined)
                    .map(([kw, arg]) => sub('%s=%r', kw, arg)))
                .join(', ')
        return sub('%s(%s)', this.constructor.name, args_str)
    }

    toString() {
        return this[util.inspect.custom]()
    }
})

// ===========================
// Optional and Positional Parsing
// ===========================
const Namespace = _callable(class Namespace extends _AttributeHolder() {
    /*
     *  Simple object for storing attributes.
     *
     *  Implements equality by attribute names and values, and provides a simple
     *  string representation.
     */

    constructor(options = {}) {
        super()
        Object.assign(this, options)
    }
})

// unset string tag to mimic plain object
Namespace.prototype[Symbol.toStringTag] = undefined


const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {

    constructor() {
        let [
            description,
            prefix_chars,
            argument_default,
            conflict_handler
        ] = _parse_opts(arguments, {
            description: no_default,
            prefix_chars: no_default,
            argument_default: no_default,
            conflict_handler: no_default
        })

        this.description = description
        this.argument_default = argument_default
        this.prefix_chars = prefix_chars
        this.conflict_handler = conflict_handler

        // set up registries
        this._registries = {}

        // register actions
        this.register('action', undefined, _StoreAction)
        this.register('action', 'store', _StoreAction)
        this.register('action', 'store_const', _StoreConstAction)
        this.register('action', 'store_true', _StoreTrueAction)
        this.register('action', 'store_false', _StoreFalseAction)
        this.register('action', 'append', _AppendAction)
        this.register('action', 'append_const', _AppendConstAction)
        this.register('action', 'count', _CountAction)
        this.register('action', 'help', _HelpAction)
        this.register('action', 'version', _VersionAction)
        this.register('action', 'parsers', _SubParsersAction)
        this.register('action', 'extend', _ExtendAction)
        // LEGACY (v1 compatibility): camelcase variants
        ;[ 'storeConst', 'storeTrue', 'storeFalse', 'appendConst' ].forEach(old_name => {
            let new_name = _to_new_name(old_name)
            this.register('action', old_name, util.deprecate(this._registry_get('action', new_name),
                sub('{action: "%s"} is renamed to {action: "%s"}', old_name, new_name)))
        })
        // end

        // raise an exception if the conflict handler is invalid
        this._get_handler()

        // action storage
        this._actions = []
        this._option_string_actions = {}

        // groups
        this._action_groups = []
        this._mutually_exclusive_groups = []

        // defaults storage
        this._defaults = {}

        // determines whether an "option" looks like a negative number
        this._negative_number_matcher = /^-\d+$|^-\d*\.\d+$/

        // whether or not there are any optionals that look like negative
        // numbers -- uses a list so it can be shared and edited
        this._has_negative_number_optionals = []
    }

    // ====================
    // Registration methods
    // ====================
    register(registry_name, value, object) {
        let registry = setdefault(this._registries, registry_name, {})
        registry[value] = object
    }

    _registry_get(registry_name, value, default_value = undefined) {
        return getattr(this._registries[registry_name], value, default_value)
    }

    // ==================================
    // Namespace default accessor methods
    // ==================================
    set_defaults(kwargs) {
        Object.assign(this._defaults, kwargs)

        // if these defaults match any existing arguments, replace
        // the previous default on the object with the new one
        for (let action of this._actions) {
            if (action.dest in kwargs) {
                action.default = kwargs[action.dest]
            }
        }
    }

    get_default(dest) {
        for (let action of this._actions) {
            if (action.dest === dest && action.default !== undefined) {
                return action.default
            }
        }
        return this._defaults[dest]
    }


    // =======================
    // Adding argument actions
    // =======================
    add_argument() {
        /*
         *  add_argument(dest, ..., name=value, ...)
         *  add_argument(option_string, option_string, ..., name=value, ...)
         */
        let [
            args,
            kwargs
        ] = _parse_opts(arguments, {
            '*args': no_default,
            '**kwargs': no_default
        })
        // LEGACY (v1 compatibility), old-style add_argument([ args ], { options })
        if (args.length === 1 && Array.isArray(args[0])) {
            args = args[0]
            deprecate('argument-array',
                sub('use add_argument(%(args)s, {...}) instead of add_argument([ %(args)s ], { ... })', {
                    args: args.map(repr).join(', ')
                }))
        }
        // end

        // if no positional args are supplied or only one is supplied and
        // it doesn't look like an option string, parse a positional
        // argument
        let chars = this.prefix_chars
        if (!args.length || args.length === 1 && !chars.includes(args[0][0])) {
            if (args.length && 'dest' in kwargs) {
                throw new TypeError('dest supplied twice for positional argument')
            }
            kwargs = this._get_positional_kwargs(...args, kwargs)

        // otherwise, we're adding an optional argument
        } else {
            kwargs = this._get_optional_kwargs(...args, kwargs)
        }

        // if no default was supplied, use the parser-level default
        if (!('default' in kwargs)) {
            let dest = kwargs.dest
            if (dest in this._defaults) {
                kwargs.default = this._defaults[dest]
            } else if (this.argument_default !== undefined) {
                kwargs.default = this.argument_default
            }
        }

        // create the action object, and add it to the parser
        let action_class = this._pop_action_class(kwargs)
        if (typeof action_class !== 'function') {
            throw new TypeError(sub('unknown action "%s"', action_class))
        }
        // eslint-disable-next-line new-cap
        let action = new action_class(kwargs)

        // raise an error if the action type is not callable
        let type_func = this._registry_get('type', action.type, action.type)
        if (typeof type_func !== 'function') {
            throw new TypeError(sub('%r is not callable', type_func))
        }

        if (type_func === FileType) {
            throw new TypeError(sub('%r is a FileType class object, instance of it' +
                                    ' must be passed', type_func))
        }

        // raise an error if the metavar does not match the type
        if ('_get_formatter' in this) {
            try {
                this._get_formatter()._format_args(action, undefined)
            } catch (err) {
                // check for 'invalid nargs value' is an artifact of TypeError and ValueError in js being the same
                if (err instanceof TypeError && err.message !== 'invalid nargs value') {
                    throw new TypeError('length of metavar tuple does not match nargs')
                } else {
                    throw err
                }
            }
        }

        return this._add_action(action)
    }

    add_argument_group() {
        let group = _ArgumentGroup(this, ...arguments)
        this._action_groups.push(group)
        return group
    }

    add_mutually_exclusive_group() {
        // eslint-disable-next-line no-use-before-define
        let group = _MutuallyExclusiveGroup(this, ...arguments)
        this._mutually_exclusive_groups.push(group)
        return group
    }

    _add_action(action) {
        // resolve any conflicts
        this._check_conflict(action)

        // add to actions list
        this._actions.push(action)
        action.container = this

        // index the action by any option strings it has
        for (let option_string of action.option_strings) {
            this._option_string_actions[option_string] = action
        }

        // set the flag if any option strings look like negative numbers
        for (let option_string of action.option_strings) {
            if (this._negative_number_matcher.test(option_string)) {
                if (!this._has_negative_number_optionals.length) {
                    this._has_negative_number_optionals.push(true)
                }
            }
        }

        // return the created action
        return action
    }

    _remove_action(action) {
        _array_remove(this._actions, action)
    }

    _add_container_actions(container) {
        // collect groups by titles
        let title_group_map = {}
        for (let group of this._action_groups) {
            if (group.title in title_group_map) {
                let msg = 'cannot merge actions - two groups are named %r'
                throw new TypeError(sub(msg, group.title))
            }
            title_group_map[group.title] = group
        }

        // map each action to its group
        let group_map = new Map()
        for (let group of container._action_groups) {

            // if a group with the title exists, use that, otherwise
            // create a new group matching the container's group
            if (!(group.title in title_group_map)) {
                title_group_map[group.title] = this.add_argument_group({
                    title: group.title,
                    description: group.description,
                    conflict_handler: group.conflict_handler
                })
            }

            // map the actions to their new group
            for (let action of group._group_actions) {
                group_map.set(action, title_group_map[group.title])
            }
        }

        // add container's mutually exclusive groups
        // NOTE: if add_mutually_exclusive_group ever gains title= and
        // description= then this code will need to be expanded as above
        for (let group of container._mutually_exclusive_groups) {
            let mutex_group = this.add_mutually_exclusive_group({
                required: group.required
            })

            // map the actions to their new mutex group
            for (let action of group._group_actions) {
                group_map.set(action, mutex_group)
            }
        }

        // add all actions to this container or their group
        for (let action of container._actions) {
            group_map.get(action)._add_action(action)
        }
    }

    _get_positional_kwargs() {
        let [
            dest,
            kwargs
        ] = _parse_opts(arguments, {
            dest: no_default,
            '**kwargs': no_default
        })

        // make sure required is not specified
        if ('required' in kwargs) {
            let msg = "'required' is an invalid argument for positionals"
            throw new TypeError(msg)
        }

        // mark positional arguments as required if at least one is
        // always required
        if (![OPTIONAL, ZERO_OR_MORE].includes(kwargs.nargs)) {
            kwargs.required = true
        }
        if (kwargs.nargs === ZERO_OR_MORE && !('default' in kwargs)) {
            kwargs.required = true
        }

        // return the keyword arguments with no option strings
        return Object.assign(kwargs, { dest, option_strings: [] })
    }

    _get_optional_kwargs() {
        let [
            args,
            kwargs
        ] = _parse_opts(arguments, {
            '*args': no_default,
            '**kwargs': no_default
        })

        // determine short and long option strings
        let option_strings = []
        let long_option_strings = []
        let option_string
        for (option_string of args) {
            // error on strings that don't start with an appropriate prefix
            if (!this.prefix_chars.includes(option_string[0])) {
                let args = {option: option_string,
                            prefix_chars: this.prefix_chars}
                let msg = 'invalid option string %(option)r: ' +
                          'must start with a character %(prefix_chars)r'
                throw new TypeError(sub(msg, args))
            }

            // strings starting with two prefix characters are long options
            option_strings.push(option_string)
            if (option_string.length > 1 && this.prefix_chars.includes(option_string[1])) {
                long_option_strings.push(option_string)
            }
        }

        // infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
        let dest = kwargs.dest
        delete kwargs.dest
        if (dest === undefined) {
            let dest_option_string
            if (long_option_strings.length) {
                dest_option_string = long_option_strings[0]
            } else {
                dest_option_string = option_strings[0]
            }
            dest = _string_lstrip(dest_option_string, this.prefix_chars)
            if (!dest) {
                let msg = 'dest= is required for options like %r'
                throw new TypeError(sub(msg, option_string))
            }
            dest = dest.replace(/-/g, '_')
        }

        // return the updated keyword arguments
        return Object.assign(kwargs, { dest, option_strings })
    }

    _pop_action_class(kwargs, default_value = undefined) {
        let action = getattr(kwargs, 'action', default_value)
        delete kwargs.action
        return this._registry_get('action', action, action)
    }

    _get_handler() {
        // determine function from conflict handler string
        let handler_func_name = sub('_handle_conflict_%s', this.conflict_handler)
        if (typeof this[handler_func_name] === 'function') {
            return this[handler_func_name]
        } else {
            let msg = 'invalid conflict_resolution value: %r'
            throw new TypeError(sub(msg, this.conflict_handler))
        }
    }

    _check_conflict(action) {

        // find all options that conflict with this option
        let confl_optionals = []
        for (let option_string of action.option_strings) {
            if (hasattr(this._option_string_actions, option_string)) {
                let confl_optional = this._option_string_actions[option_string]
                confl_optionals.push([ option_string, confl_optional ])
            }
        }

        // resolve any conflicts
        if (confl_optionals.length) {
            let conflict_handler = this._get_handler()
            conflict_handler.call(this, action, confl_optionals)
        }
    }

    _handle_conflict_error(action, conflicting_actions) {
        let message = conflicting_actions.length === 1 ?
            'conflicting option string: %s' :
            'conflicting option strings: %s'
        let conflict_string = conflicting_actions.map(([ option_string/*, action*/ ]) => option_string).join(', ')
        throw new ArgumentError(action, sub(message, conflict_string))
    }

    _handle_conflict_resolve(action, conflicting_actions) {

        // remove all conflicting options
        for (let [ option_string, action ] of conflicting_actions) {

            // remove the conflicting option
            _array_remove(action.option_strings, option_string)
            delete this._option_string_actions[option_string]

            // if the option now has no option string, remove it from the
            // container holding it
            if (!action.option_strings.length) {
                action.container._remove_action(action)
            }
        }
    }
}))


const _ArgumentGroup = _callable(class _ArgumentGroup extends _ActionsContainer {

    constructor() {
        let [
            container,
            title,
            description,
            kwargs
        ] = _parse_opts(arguments, {
            container: no_default,
            title: undefined,
            description: undefined,
            '**kwargs': no_default
        })

        // add any missing keyword arguments by checking the container
        setdefault(kwargs, 'conflict_handler', container.conflict_handler)
        setdefault(kwargs, 'prefix_chars', container.prefix_chars)
        setdefault(kwargs, 'argument_default', container.argument_default)
        super(Object.assign({ description }, kwargs))

        // group attributes
        this.title = title
        this._group_actions = []

        // share most attributes with the container
        this._registries = container._registries
        this._actions = container._actions
        this._option_string_actions = container._option_string_actions
        this._defaults = container._defaults
        this._has_negative_number_optionals =
            container._has_negative_number_optionals
        this._mutually_exclusive_groups = container._mutually_exclusive_groups
    }

    _add_action(action) {
        action = super._add_action(action)
        this._group_actions.push(action)
        return action
    }

    _remove_action(action) {
        super._remove_action(action)
        _array_remove(this._group_actions, action)
    }
})


const _MutuallyExclusiveGroup = _callable(class _MutuallyExclusiveGroup extends _ArgumentGroup {

    constructor() {
        let [
            container,
            required
        ] = _parse_opts(arguments, {
            container: no_default,
            required: false
        })

        super(container)
        this.required = required
        this._container = container
    }

    _add_action(action) {
        if (action.required) {
            let msg = 'mutually exclusive arguments must be optional'
            throw new TypeError(msg)
        }
        action = this._container._add_action(action)
        this._group_actions.push(action)
        return action
    }

    _remove_action(action) {
        this._container._remove_action(action)
        _array_remove(this._group_actions, action)
    }
})


const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _AttributeHolder(_ActionsContainer) {
    /*
     *  Object for parsing command line strings into Python objects.
     *
     *  Keyword Arguments:
     *      - prog -- The name of the program (default: sys.argv[0])
     *      - usage -- A usage message (default: auto-generated from arguments)
     *      - description -- A description of what the program does
     *      - epilog -- Text following the argument descriptions
     *      - parents -- Parsers whose arguments should be copied into this one
     *      - formatter_class -- HelpFormatter class for printing help messages
     *      - prefix_chars -- Characters that prefix optional arguments
     *      - fromfile_prefix_chars -- Characters that prefix files containing
     *          additional arguments
     *      - argument_default -- The default value for all arguments
     *      - conflict_handler -- String indicating how to handle conflicts
     *      - add_help -- Add a -h/-help option
     *      - allow_abbrev -- Allow long options to be abbreviated unambiguously
     *      - exit_on_error -- Determines whether or not ArgumentParser exits with
     *          error info when an error occurs
     */

    constructor() {
        let [
            prog,
            usage,
            description,
            epilog,
            parents,
            formatter_class,
            prefix_chars,
            fromfile_prefix_chars,
            argument_default,
            conflict_handler,
            add_help,
            allow_abbrev,
            exit_on_error,
            debug, // LEGACY (v1 compatibility), debug mode
            version // LEGACY (v1 compatibility), version
        ] = _parse_opts(arguments, {
            prog: undefined,
            usage: undefined,
            description: undefined,
            epilog: undefined,
            parents: [],
            formatter_class: HelpFormatter,
            prefix_chars: '-',
            fromfile_prefix_chars: undefined,
            argument_default: undefined,
            conflict_handler: 'error',
            add_help: true,
            allow_abbrev: true,
            exit_on_error: true,
            debug: undefined, // LEGACY (v1 compatibility), debug mode
            version: undefined // LEGACY (v1 compatibility), version
        })

        // LEGACY (v1 compatibility)
        if (debug !== undefined) {
            deprecate('debug',
                'The "debug" argument to ArgumentParser is deprecated. Please ' +
                'override ArgumentParser.exit function instead.'
            )
        }

        if (version !== undefined) {
            deprecate('version',
                'The "version" argument to ArgumentParser is deprecated. Please use ' +
                "add_argument(..., { action: 'version', version: 'N', ... }) instead."
            )
        }
        // end

        super({
            description,
            prefix_chars,
            argument_default,
            conflict_handler
        })

        // default setting for prog
        if (prog === undefined) {
            prog = path.basename(get_argv()[0] || '')
        }

        this.prog = prog
        this.usage = usage
        this.epilog = epilog
        this.formatter_class = formatter_class
        this.fromfile_prefix_chars = fromfile_prefix_chars
        this.add_help = add_help
        this.allow_abbrev = allow_abbrev
        this.exit_on_error = exit_on_error
        // LEGACY (v1 compatibility), debug mode
        this.debug = debug
        // end

        this._positionals = this.add_argument_group('positional arguments')
        this._optionals = this.add_argument_group('optional arguments')
        this._subparsers = undefined

        // register types
        function identity(string) {
            return string
        }
        this.register('type', undefined, identity)
        this.register('type', null, identity)
        this.register('type', 'auto', identity)
        this.register('type', 'int', function (x) {
            let result = Number(x)
            if (!Number.isInteger(result)) {
                throw new TypeError(sub('could not convert string to int: %r', x))
            }
            return result
        })
        this.register('type', 'float', function (x) {
            let result = Number(x)
            if (isNaN(result)) {
                throw new TypeError(sub('could not convert string to float: %r', x))
            }
            return result
        })
        this.register('type', 'str', String)
        // LEGACY (v1 compatibility): custom types
        this.register('type', 'string',
            util.deprecate(String, 'use {type:"str"} or {type:String} instead of {type:"string"}'))
        // end

        // add help argument if necessary
        // (using explicit default to override global argument_default)
        let default_prefix = prefix_chars.includes('-') ? '-' : prefix_chars[0]
        if (this.add_help) {
            this.add_argument(
                default_prefix + 'h',
                default_prefix.repeat(2) + 'help',
                {
                    action: 'help',
                    default: SUPPRESS,
                    help: 'show this help message and exit'
                }
            )
        }
        // LEGACY (v1 compatibility), version
        if (version) {
            this.add_argument(
                default_prefix + 'v',
                default_prefix.repeat(2) + 'version',
                {
                    action: 'version',
                    default: SUPPRESS,
                    version: this.version,
                    help: "show program's version number and exit"
                }
            )
        }
        // end

        // add parent arguments and defaults
        for (let parent of parents) {
            this._add_container_actions(parent)
            Object.assign(this._defaults, parent._defaults)
        }
    }

    // =======================
    // Pretty __repr__ methods
    // =======================
    _get_kwargs() {
        let names = [
            'prog',
            'usage',
            'description',
            'formatter_class',
            'conflict_handler',
            'add_help'
        ]
        return names.map(name => [ name, getattr(this, name) ])
    }

    // ==================================
    // Optional/Positional adding methods
    // ==================================
    add_subparsers() {
        let [
            kwargs
        ] = _parse_opts(arguments, {
            '**kwargs': no_default
        })

        if (this._subparsers !== undefined) {
            this.error('cannot have multiple subparser arguments')
        }

        // add the parser class to the arguments if it's not present
        setdefault(kwargs, 'parser_class', this.constructor)

        if ('title' in kwargs || 'description' in kwargs) {
            let title = getattr(kwargs, 'title', 'subcommands')
            let description = getattr(kwargs, 'description', undefined)
            delete kwargs.title
            delete kwargs.description
            this._subparsers = this.add_argument_group(title, description)
        } else {
            this._subparsers = this._positionals
        }

        // prog defaults to the usage message of this parser, skipping
        // optional arguments and with no "usage:" prefix
        if (kwargs.prog === undefined) {
            let formatter = this._get_formatter()
            let positionals = this._get_positional_actions()
            let groups = this._mutually_exclusive_groups
            formatter.add_usage(this.usage, positionals, groups, '')
            kwargs.prog = formatter.format_help().trim()
        }

        // create the parsers action and add it to the positionals list
        let parsers_class = this._pop_action_class(kwargs, 'parsers')
        // eslint-disable-next-line new-cap
        let action = new parsers_class(Object.assign({ option_strings: [] }, kwargs))
        this._subparsers._add_action(action)

        // return the created parsers action
        return action
    }

    _add_action(action) {
        if (action.option_strings.length) {
            this._optionals._add_action(action)
        } else {
            this._positionals._add_action(action)
        }
        return action
    }

    _get_optional_actions() {
        return this._actions.filter(action => action.option_strings.length)
    }

    _get_positional_actions() {
        return this._actions.filter(action => !action.option_strings.length)
    }

    // =====================================
    // Command line argument parsing methods
    // =====================================
    parse_args(args = undefined, namespace = undefined) {
        let argv
        [ args, argv ] = this.parse_known_args(args, namespace)
        if (argv && argv.length > 0) {
            let msg = 'unrecognized arguments: %s'
            this.error(sub(msg, argv.join(' ')))
        }
        return args
    }

    parse_known_args(args = undefined, namespace = undefined) {
        if (args === undefined) {
            args = get_argv().slice(1)
        }

        // default Namespace built from parser defaults
        if (namespace === undefined) {
            namespace = new Namespace()
        }

        // add any action defaults that aren't present
        for (let action of this._actions) {
            if (action.dest !== SUPPRESS) {
                if (!hasattr(namespace, action.dest)) {
                    if (action.default !== SUPPRESS) {
                        setattr(namespace, action.dest, action.default)
                    }
                }
            }
        }

        // add any parser defaults that aren't present
        for (let dest of Object.keys(this._defaults)) {
            if (!hasattr(namespace, dest)) {
                setattr(namespace, dest, this._defaults[dest])
            }
        }

        // parse the arguments and exit if there are any errors
        if (this.exit_on_error) {
            try {
                [ namespace, args ] = this._parse_known_args(args, namespace)
            } catch (err) {
                if (err instanceof ArgumentError) {
                    this.error(err.message)
                } else {
                    throw err
                }
            }
        } else {
            [ namespace, args ] = this._parse_known_args(args, namespace)
        }

        if (hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) {
            args = args.concat(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
            delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
        }

        return [ namespace, args ]
    }

    _parse_known_args(arg_strings, namespace) {
        // replace arg strings that are file references
        if (this.fromfile_prefix_chars !== undefined) {
            arg_strings = this._read_args_from_files(arg_strings)
        }

        // map all mutually exclusive arguments to the other arguments
        // they can't occur with
        let action_conflicts = new Map()
        for (let mutex_group of this._mutually_exclusive_groups) {
            let group_actions = mutex_group._group_actions
            for (let [ i, mutex_action ] of Object.entries(mutex_group._group_actions)) {
                let conflicts = action_conflicts.get(mutex_action) || []
                conflicts = conflicts.concat(group_actions.slice(0, +i))
                conflicts = conflicts.concat(group_actions.slice(+i + 1))
                action_conflicts.set(mutex_action, conflicts)
            }
        }

        // find all option indices, and determine the arg_string_pattern
        // which has an 'O' if there is an option at an index,
        // an 'A' if there is an argument, or a '-' if there is a '--'
        let option_string_indices = {}
        let arg_string_pattern_parts = []
        let arg_strings_iter = Object.entries(arg_strings)[Symbol.iterator]()
        for (let [ i, arg_string ] of arg_strings_iter) {

            // all args after -- are non-options
            if (arg_string === '--') {
                arg_string_pattern_parts.push('-')
                for ([ i, arg_string ] of arg_strings_iter) {
                    arg_string_pattern_parts.push('A')
                }

            // otherwise, add the arg to the arg strings
            // and note the index if it was an option
            } else {
                let option_tuple = this._parse_optional(arg_string)
                let pattern
                if (option_tuple === undefined) {
                    pattern = 'A'
                } else {
                    option_string_indices[i] = option_tuple
                    pattern = 'O'
                }
                arg_string_pattern_parts.push(pattern)
            }
        }

        // join the pieces together to form the pattern
        let arg_strings_pattern = arg_string_pattern_parts.join('')

        // converts arg strings to the appropriate and then takes the action
        let seen_actions = new Set()
        let seen_non_default_actions = new Set()
        let extras

        let take_action = (action, argument_strings, option_string = undefined) => {
            seen_actions.add(action)
            let argument_values = this._get_values(action, argument_strings)

            // error if this argument is not allowed with other previously
            // seen arguments, assuming that actions that use the default
            // value don't really count as "present"
            if (argument_values !== action.default) {
                seen_non_default_actions.add(action)
                for (let conflict_action of action_conflicts.get(action) || []) {
                    if (seen_non_default_actions.has(conflict_action)) {
                        let msg = 'not allowed with argument %s'
                        let action_name = _get_action_name(conflict_action)
                        throw new ArgumentError(action, sub(msg, action_name))
                    }
                }
            }

            // take the action if we didn't receive a SUPPRESS value
            // (e.g. from a default)
            if (argument_values !== SUPPRESS) {
                action(this, namespace, argument_values, option_string)
            }
        }

        // function to convert arg_strings into an optional action
        let consume_optional = start_index => {

            // get the optional identified at this index
            let option_tuple = option_string_indices[start_index]
            let [ action, option_string, explicit_arg ] = option_tuple

            // identify additional optionals in the same arg string
            // (e.g. -xyz is the same as -x -y -z if no args are required)
            let action_tuples = []
            let stop
            for (;;) {

                // if we found no optional action, skip it
                if (action === undefined) {
                    extras.push(arg_strings[start_index])
                    return start_index + 1
                }

                // if there is an explicit argument, try to match the
                // optional's string arguments to only this
                if (explicit_arg !== undefined) {
                    let arg_count = this._match_argument(action, 'A')

                    // if the action is a single-dash option and takes no
                    // arguments, try to parse more single-dash options out
                    // of the tail of the option string
                    let chars = this.prefix_chars
                    if (arg_count === 0 && !chars.includes(option_string[1])) {
                        action_tuples.push([ action, [], option_string ])
                        let char = option_string[0]
                        option_string = char + explicit_arg[0]
                        let new_explicit_arg = explicit_arg.slice(1) || undefined
                        let optionals_map = this._option_string_actions
                        if (hasattr(optionals_map, option_string)) {
                            action = optionals_map[option_string]
                            explicit_arg = new_explicit_arg
                        } else {
                            let msg = 'ignored explicit argument %r'
                            throw new ArgumentError(action, sub(msg, explicit_arg))
                        }

                    // if the action expect exactly one argument, we've
                    // successfully matched the option; exit the loop
                    } else if (arg_count === 1) {
                        stop = start_index + 1
                        let args = [ explicit_arg ]
                        action_tuples.push([ action, args, option_string ])
                        break

                    // error if a double-dash option did not use the
                    // explicit argument
                    } else {
                        let msg = 'ignored explicit argument %r'
                        throw new ArgumentError(action, sub(msg, explicit_arg))
                    }

                // if there is no explicit argument, try to match the
                // optional's string arguments with the following strings
                // if successful, exit the loop
                } else {
                    let start = start_index + 1
                    let selected_patterns = arg_strings_pattern.slice(start)
                    let arg_count = this._match_argument(action, selected_patterns)
                    stop = start + arg_count
                    let args = arg_strings.slice(start, stop)
                    action_tuples.push([ action, args, option_string ])
                    break
                }
            }

            // add the Optional to the list and return the index at which
            // the Optional's string args stopped
            assert(action_tuples.length)
            for (let [ action, args, option_string ] of action_tuples) {
                take_action(action, args, option_string)
            }
            return stop
        }

        // the list of Positionals left to be parsed; this is modified
        // by consume_positionals()
        let positionals = this._get_positional_actions()

        // function to convert arg_strings into positional actions
        let consume_positionals = start_index => {
            // match as many Positionals as possible
            let selected_pattern = arg_strings_pattern.slice(start_index)
            let arg_counts = this._match_arguments_partial(positionals, selected_pattern)

            // slice off the appropriate arg strings for each Positional
            // and add the Positional and its args to the list
            for (let i = 0; i < positionals.length && i < arg_counts.length; i++) {
                let action = positionals[i]
                let arg_count = arg_counts[i]
                let args = arg_strings.slice(start_index, start_index + arg_count)
                start_index += arg_count
                take_action(action, args)
            }

            // slice off the Positionals that we just parsed and return the
            // index at which the Positionals' string args stopped
            positionals = positionals.slice(arg_counts.length)
            return start_index
        }

        // consume Positionals and Optionals alternately, until we have
        // passed the last option string
        extras = []
        let start_index = 0
        let max_option_string_index = Math.max(-1, ...Object.keys(option_string_indices).map(Number))
        while (start_index <= max_option_string_index) {

            // consume any Positionals preceding the next option
            let next_option_string_index = Math.min(
                // eslint-disable-next-line no-loop-func
                ...Object.keys(option_string_indices).map(Number).filter(index => index >= start_index)
            )
            if (start_index !== next_option_string_index) {
                let positionals_end_index = consume_positionals(start_index)

                // only try to parse the next optional if we didn't consume
                // the option string during the positionals parsing
                if (positionals_end_index > start_index) {
                    start_index = positionals_end_index
                    continue
                } else {
                    start_index = positionals_end_index
                }
            }

            // if we consumed all the positionals we could and we're not
            // at the index of an option string, there were extra arguments
            if (!(start_index in option_string_indices)) {
                let strings = arg_strings.slice(start_index, next_option_string_index)
                extras = extras.concat(strings)
                start_index = next_option_string_index
            }

            // consume the next optional and any arguments for it
            start_index = consume_optional(start_index)
        }

        // consume any positionals following the last Optional
        let stop_index = consume_positionals(start_index)

        // if we didn't consume all the argument strings, there were extras
        extras = extras.concat(arg_strings.slice(stop_index))

        // make sure all required actions were present and also convert
        // action defaults which were not given as arguments
        let required_actions = []
        for (let action of this._actions) {
            if (!seen_actions.has(action)) {
                if (action.required) {
                    required_actions.push(_get_action_name(action))
                } else {
                    // Convert action default now instead of doing it before
                    // parsing arguments to avoid calling convert functions
                    // twice (which may fail) if the argument was given, but
                    // only if it was defined already in the namespace
                    if (action.default !== undefined &&
                        typeof action.default === 'string' &&
                        hasattr(namespace, action.dest) &&
                        action.default === getattr(namespace, action.dest)) {
                        setattr(namespace, action.dest,
                                this._get_value(action, action.default))
                    }
                }
            }
        }

        if (required_actions.length) {
            this.error(sub('the following arguments are required: %s',
                       required_actions.join(', ')))
        }

        // make sure all required groups had one option present
        for (let group of this._mutually_exclusive_groups) {
            if (group.required) {
                let no_actions_used = true
                for (let action of group._group_actions) {
                    if (seen_non_default_actions.has(action)) {
                        no_actions_used = false
                        break
                    }
                }

                // if no actions were used, report the error
                if (no_actions_used) {
                    let names = group._group_actions
                        .filter(action => action.help !== SUPPRESS)
                        .map(action => _get_action_name(action))
                    let msg = 'one of the arguments %s is required'
                    this.error(sub(msg, names.join(' ')))
                }
            }
        }

        // return the updated namespace and the extra arguments
        return [ namespace, extras ]
    }

    _read_args_from_files(arg_strings) {
        // expand arguments referencing files
        let new_arg_strings = []
        for (let arg_string of arg_strings) {

            // for regular arguments, just add them back into the list
            if (!arg_string || !this.fromfile_prefix_chars.includes(arg_string[0])) {
                new_arg_strings.push(arg_string)

            // replace arguments referencing files with the file content
            } else {
                try {
                    let args_file = fs.readFileSync(arg_string.slice(1), 'utf8')
                    let arg_strings = []
                    for (let arg_line of splitlines(args_file)) {
                        for (let arg of this.convert_arg_line_to_args(arg_line)) {
                            arg_strings.push(arg)
                        }
                    }
                    arg_strings = this._read_args_from_files(arg_strings)
                    new_arg_strings = new_arg_strings.concat(arg_strings)
                } catch (err) {
                    this.error(err.message)
                }
            }
        }

        // return the modified argument list
        return new_arg_strings
    }

    convert_arg_line_to_args(arg_line) {
        return [arg_line]
    }

    _match_argument(action, arg_strings_pattern) {
        // match the pattern for this action to the arg strings
        let nargs_pattern = this._get_nargs_pattern(action)
        let match = arg_strings_pattern.match(new RegExp('^' + nargs_pattern))

        // raise an exception if we weren't able to find a match
        if (match === null) {
            let nargs_errors = {
                undefined: 'expected one argument',
                [OPTIONAL]: 'expected at most one argument',
                [ONE_OR_MORE]: 'expected at least one argument'
            }
            let msg = nargs_errors[action.nargs]
            if (msg === undefined) {
                msg = sub(action.nargs === 1 ? 'expected %s argument' : 'expected %s arguments', action.nargs)
            }
            throw new ArgumentError(action, msg)
        }

        // return the number of arguments matched
        return match[1].length
    }

    _match_arguments_partial(actions, arg_strings_pattern) {
        // progressively shorten the actions list by slicing off the
        // final actions until we find a match
        let result = []
        for (let i of range(actions.length, 0, -1)) {
            let actions_slice = actions.slice(0, i)
            let pattern = actions_slice.map(action => this._get_nargs_pattern(action)).join('')
            let match = arg_strings_pattern.match(new RegExp('^' + pattern))
            if (match !== null) {
                result = result.concat(match.slice(1).map(string => string.length))
                break
            }
        }

        // return the list of arg string counts
        return result
    }

    _parse_optional(arg_string) {
        // if it's an empty string, it was meant to be a positional
        if (!arg_string) {
            return undefined
        }

        // if it doesn't start with a prefix, it was meant to be positional
        if (!this.prefix_chars.includes(arg_string[0])) {
            return undefined
        }

        // if the option string is present in the parser, return the action
        if (arg_string in this._option_string_actions) {
            let action = this._option_string_actions[arg_string]
            return [ action, arg_string, undefined ]
        }

        // if it's just a single character, it was meant to be positional
        if (arg_string.length === 1) {
            return undefined
        }

        // if the option string before the "=" is present, return the action
        if (arg_string.includes('=')) {
            let [ option_string, explicit_arg ] = _string_split(arg_string, '=', 1)
            if (option_string in this._option_string_actions) {
                let action = this._option_string_actions[option_string]
                return [ action, option_string, explicit_arg ]
            }
        }

        // search through all possible prefixes of the option string
        // and all actions in the parser for possible interpretations
        let option_tuples = this._get_option_tuples(arg_string)

        // if multiple actions match, the option string was ambiguous
        if (option_tuples.length > 1) {
            let options = option_tuples.map(([ /*action*/, option_string/*, explicit_arg*/ ]) => option_string).join(', ')
            let args = {option: arg_string, matches: options}
            let msg = 'ambiguous option: %(option)s could match %(matches)s'
            this.error(sub(msg, args))

        // if exactly one action matched, this segmentation is good,
        // so return the parsed action
        } else if (option_tuples.length === 1) {
            let [ option_tuple ] = option_tuples
            return option_tuple
        }

        // if it was not found as an option, but it looks like a negative
        // number, it was meant to be positional
        // unless there are negative-number-like options
        if (this._negative_number_matcher.test(arg_string)) {
            if (!this._has_negative_number_optionals.length) {
                return undefined
            }
        }

        // if it contains a space, it was meant to be a positional
        if (arg_string.includes(' ')) {
            return undefined
        }

        // it was meant to be an optional but there is no such option
        // in this parser (though it might be a valid option in a subparser)
        return [ undefined, arg_string, undefined ]
    }

    _get_option_tuples(option_string) {
        let result = []

        // option strings starting with two prefix characters are only
        // split at the '='
        let chars = this.prefix_chars
        if (chars.includes(option_string[0]) && chars.includes(option_string[1])) {
            if (this.allow_abbrev) {
                let option_prefix, explicit_arg
                if (option_string.includes('=')) {
                    [ option_prefix, explicit_arg ] = _string_split(option_string, '=', 1)
                } else {
                    option_prefix = option_string
                    explicit_arg = undefined
                }
                for (let option_string of Object.keys(this._option_string_actions)) {
                    if (option_string.startsWith(option_prefix)) {
                        let action = this._option_string_actions[option_string]
                        let tup = [ action, option_string, explicit_arg ]
                        result.push(tup)
                    }
                }
            }

        // single character options can be concatenated with their arguments
        // but multiple character options always have to have their argument
        // separate
        } else if (chars.includes(option_string[0]) && !chars.includes(option_string[1])) {
            let option_prefix = option_string
            let explicit_arg = undefined
            let short_option_prefix = option_string.slice(0, 2)
            let short_explicit_arg = option_string.slice(2)

            for (let option_string of Object.keys(this._option_string_actions)) {
                if (option_string === short_option_prefix) {
                    let action = this._option_string_actions[option_string]
                    let tup = [ action, option_string, short_explicit_arg ]
                    result.push(tup)
                } else if (option_string.startsWith(option_prefix)) {
                    let action = this._option_string_actions[option_string]
                    let tup = [ action, option_string, explicit_arg ]
                    result.push(tup)
                }
            }

        // shouldn't ever get here
        } else {
            this.error(sub('unexpected option string: %s', option_string))
        }

        // return the collected option tuples
        return result
    }

    _get_nargs_pattern(action) {
        // in all examples below, we have to allow for '--' args
        // which are represented as '-' in the pattern
        let nargs = action.nargs
        let nargs_pattern

        // the default (None) is assumed to be a single argument
        if (nargs === undefined) {
            nargs_pattern = '(-*A-*)'

        // allow zero or one arguments
        } else if (nargs === OPTIONAL) {
            nargs_pattern = '(-*A?-*)'

        // allow zero or more arguments
        } else if (nargs === ZERO_OR_MORE) {
            nargs_pattern = '(-*[A-]*)'

        // allow one or more arguments
        } else if (nargs === ONE_OR_MORE) {
            nargs_pattern = '(-*A[A-]*)'

        // allow any number of options or arguments
        } else if (nargs === REMAINDER) {
            nargs_pattern = '([-AO]*)'

        // allow one argument followed by any number of options or arguments
        } else if (nargs === PARSER) {
            nargs_pattern = '(-*A[-AO]*)'

        // suppress action, like nargs=0
        } else if (nargs === SUPPRESS) {
            nargs_pattern = '(-*-*)'

        // all others should be integers
        } else {
            nargs_pattern = sub('(-*%s-*)', 'A'.repeat(nargs).split('').join('-*'))
        }

        // if this is an optional action, -- is not allowed
        if (action.option_strings.length) {
            nargs_pattern = nargs_pattern.replace(/-\*/g, '')
            nargs_pattern = nargs_pattern.replace(/-/g, '')
        }

        // return the pattern
        return nargs_pattern
    }

    // ========================
    // Alt command line argument parsing, allowing free intermix
    // ========================

    parse_intermixed_args(args = undefined, namespace = undefined) {
        let argv
        [ args, argv ] = this.parse_known_intermixed_args(args, namespace)
        if (argv.length) {
            let msg = 'unrecognized arguments: %s'
            this.error(sub(msg, argv.join(' ')))
        }
        return args
    }

    parse_known_intermixed_args(args = undefined, namespace = undefined) {
        // returns a namespace and list of extras
        //
        // positional can be freely intermixed with optionals.  optionals are
        // first parsed with all positional arguments deactivated.  The 'extras'
        // are then parsed.  If the parser definition is incompatible with the
        // intermixed assumptions (e.g. use of REMAINDER, subparsers) a
        // TypeError is raised.
        //
        // positionals are 'deactivated' by setting nargs and default to
        // SUPPRESS.  This blocks the addition of that positional to the
        // namespace

        let extras
        let positionals = this._get_positional_actions()
        let a = positionals.filter(action => [ PARSER, REMAINDER ].includes(action.nargs))
        if (a.length) {
            throw new TypeError(sub('parse_intermixed_args: positional arg' +
                                    ' with nargs=%s', a[0].nargs))
        }

        for (let group of this._mutually_exclusive_groups) {
            for (let action of group._group_actions) {
                if (positionals.includes(action)) {
                    throw new TypeError('parse_intermixed_args: positional in' +
                                        ' mutuallyExclusiveGroup')
                }
            }
        }

        let save_usage
        try {
            save_usage = this.usage
            let remaining_args
            try {
                if (this.usage === undefined) {
                    // capture the full usage for use in error messages
                    this.usage = this.format_usage().slice(7)
                }
                for (let action of positionals) {
                    // deactivate positionals
                    action.save_nargs = action.nargs
                    // action.nargs = 0
                    action.nargs = SUPPRESS
                    action.save_default = action.default
                    action.default = SUPPRESS
                }
                [ namespace, remaining_args ] = this.parse_known_args(args,
                                                                      namespace)
                for (let action of positionals) {
                    // remove the empty positional values from namespace
                    let attr = getattr(namespace, action.dest)
                    if (Array.isArray(attr) && attr.length === 0) {
                        // eslint-disable-next-line no-console
                        console.warn(sub('Do not expect %s in %s', action.dest, namespace))
                        delattr(namespace, action.dest)
                    }
                }
            } finally {
                // restore nargs and usage before exiting
                for (let action of positionals) {
                    action.nargs = action.save_nargs
                    action.default = action.save_default
                }
            }
            let optionals = this._get_optional_actions()
            try {
                // parse positionals.  optionals aren't normally required, but
                // they could be, so make sure they aren't.
                for (let action of optionals) {
                    action.save_required = action.required
                    action.required = false
                }
                for (let group of this._mutually_exclusive_groups) {
                    group.save_required = group.required
                    group.required = false
                }
                [ namespace, extras ] = this.parse_known_args(remaining_args,
                                                              namespace)
            } finally {
                // restore parser values before exiting
                for (let action of optionals) {
                    action.required = action.save_required
                }
                for (let group of this._mutually_exclusive_groups) {
                    group.required = group.save_required
                }
            }
        } finally {
            this.usage = save_usage
        }
        return [ namespace, extras ]
    }

    // ========================
    // Value conversion methods
    // ========================
    _get_values(action, arg_strings) {
        // for everything but PARSER, REMAINDER args, strip out first '--'
        if (![PARSER, REMAINDER].includes(action.nargs)) {
            try {
                _array_remove(arg_strings, '--')
            } catch (err) {}
        }

        let value
        // optional argument produces a default when not present
        if (!arg_strings.length && action.nargs === OPTIONAL) {
            if (action.option_strings.length) {
                value = action.const
            } else {
                value = action.default
            }
            if (typeof value === 'string') {
                value = this._get_value(action, value)
                this._check_value(action, value)
            }

        // when nargs='*' on a positional, if there were no command-line
        // args, use the default if it is anything other than None
        } else if (!arg_strings.length && action.nargs === ZERO_OR_MORE &&
              !action.option_strings.length) {
            if (action.default !== undefined) {
                value = action.default
            } else {
                value = arg_strings
            }
            this._check_value(action, value)

        // single argument or optional argument produces a single value
        } else if (arg_strings.length === 1 && [undefined, OPTIONAL].includes(action.nargs)) {
            let arg_string = arg_strings[0]
            value = this._get_value(action, arg_string)
            this._check_value(action, value)

        // REMAINDER arguments convert all values, checking none
        } else if (action.nargs === REMAINDER) {
            value = arg_strings.map(v => this._get_value(action, v))

        // PARSER arguments convert all values, but check only the first
        } else if (action.nargs === PARSER) {
            value = arg_strings.map(v => this._get_value(action, v))
            this._check_value(action, value[0])

        // SUPPRESS argument does not put anything in the namespace
        } else if (action.nargs === SUPPRESS) {
            value = SUPPRESS

        // all other types of nargs produce a list
        } else {
            value = arg_strings.map(v => this._get_value(action, v))
            for (let v of value) {
                this._check_value(action, v)
            }
        }

        // return the converted value
        return value
    }

    _get_value(action, arg_string) {
        let type_func = this._registry_get('type', action.type, action.type)
        if (typeof type_func !== 'function') {
            let msg = '%r is not callable'
            throw new ArgumentError(action, sub(msg, type_func))
        }

        // convert the value to the appropriate type
        let result
        try {
            try {
                result = type_func(arg_string)
            } catch (err) {
                // Dear TC39, why would you ever consider making es6 classes not callable?
                // We had one universal interface, [[Call]], which worked for anything
                // (with familiar this-instanceof guard for classes). Now we have two.
                if (err instanceof TypeError &&
                    /Class constructor .* cannot be invoked without 'new'/.test(err.message)) {
                    // eslint-disable-next-line new-cap
                    result = new type_func(arg_string)
                } else {
                    throw err
                }
            }

        } catch (err) {
            // ArgumentTypeErrors indicate errors
            if (err instanceof ArgumentTypeError) {
                //let name = getattr(action.type, 'name', repr(action.type))
                let msg = err.message
                throw new ArgumentError(action, msg)

            // TypeErrors or ValueErrors also indicate errors
            } else if (err instanceof TypeError) {
                let name = getattr(action.type, 'name', repr(action.type))
                let args = {type: name, value: arg_string}
                let msg = 'invalid %(type)s value: %(value)r'
                throw new ArgumentError(action, sub(msg, args))
            } else {
                throw err
            }
        }

        // return the converted value
        return result
    }

    _check_value(action, value) {
        // converted value must be one of the choices (if specified)
        if (action.choices !== undefined && !_choices_to_array(action.choices).includes(value)) {
            let args = {value,
                        choices: _choices_to_array(action.choices).map(repr).join(', ')}
            let msg = 'invalid choice: %(value)r (choose from %(choices)s)'
            throw new ArgumentError(action, sub(msg, args))
        }
    }

    // =======================
    // Help-formatting methods
    // =======================
    format_usage() {
        let formatter = this._get_formatter()
        formatter.add_usage(this.usage, this._actions,
                            this._mutually_exclusive_groups)
        return formatter.format_help()
    }

    format_help() {
        let formatter = this._get_formatter()

        // usage
        formatter.add_usage(this.usage, this._actions,
                            this._mutually_exclusive_groups)

        // description
        formatter.add_text(this.description)

        // positionals, optionals and user-defined groups
        for (let action_group of this._action_groups) {
            formatter.start_section(action_group.title)
            formatter.add_text(action_group.description)
            formatter.add_arguments(action_group._group_actions)
            formatter.end_section()
        }

        // epilog
        formatter.add_text(this.epilog)

        // determine help from format above
        return formatter.format_help()
    }

    _get_formatter() {
        // eslint-disable-next-line new-cap
        return new this.formatter_class({ prog: this.prog })
    }

    // =====================
    // Help-printing methods
    // =====================
    print_usage(file = undefined) {
        if (file === undefined) file = process.stdout
        this._print_message(this.format_usage(), file)
    }

    print_help(file = undefined) {
        if (file === undefined) file = process.stdout
        this._print_message(this.format_help(), file)
    }

    _print_message(message, file = undefined) {
        if (message) {
            if (file === undefined) file = process.stderr
            file.write(message)
        }
    }

    // ===============
    // Exiting methods
    // ===============
    exit(status = 0, message = undefined) {
        if (message) {
            this._print_message(message, process.stderr)
        }
        process.exit(status)
    }

    error(message) {
        /*
         *  error(message: string)
         *
         *  Prints a usage message incorporating the message to stderr and
         *  exits.
         *
         *  If you override this in a subclass, it should not return -- it
         *  should either exit or raise an exception.
         */

        // LEGACY (v1 compatibility), debug mode
        if (this.debug === true) throw new Error(message)
        // end
        this.print_usage(process.stderr)
        let args = {prog: this.prog, message: message}
        this.exit(2, sub('%(prog)s: error: %(message)s\n', args))
    }
}))


module.exports = {
    ArgumentParser,
    ArgumentError,
    ArgumentTypeError,
    BooleanOptionalAction,
    FileType,
    HelpFormatter,
    ArgumentDefaultsHelpFormatter,
    RawDescriptionHelpFormatter,
    RawTextHelpFormatter,
    MetavarTypeHelpFormatter,
    Namespace,
    Action,
    ONE_OR_MORE,
    OPTIONAL,
    PARSER,
    REMAINDER,
    SUPPRESS,
    ZERO_OR_MORE
}

// LEGACY (v1 compatibility), Const alias
Object.defineProperty(module.exports, 'Const', {
    get() {
        let result = {}
        Object.entries({ ONE_OR_MORE, OPTIONAL, PARSER, REMAINDER, SUPPRESS, ZERO_OR_MORE }).forEach(([ n, v ]) => {
            Object.defineProperty(result, n, {
                get() {
                    deprecate(n, sub('use argparse.%s instead of argparse.Const.%s', n, n))
                    return v
                }
            })
        })
        Object.entries({ _UNRECOGNIZED_ARGS_ATTR }).forEach(([ n, v ]) => {
            Object.defineProperty(result, n, {
                get() {
                    deprecate(n, sub('argparse.Const.%s is an internal symbol and will no longer be available', n))
                    return v
                }
            })
        })
        return result
    },
    enumerable: false
})
// end
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              